//Java 模板实现staticintN=100010;staticint n,m;staticint u,v,w;// 使用并查集判断每个节点的归属集合// p代表点 1 ~ n 的父节点是什么staticint[] p =newint[N];// 查询节点 x 的根节点(只有根节点才可以满足p[x] = x)// 根节点的p[x]代表的就是集合本身编号staticintfindRoot(int x){if(p[x]!= x){
p[x]=findRoot(p[x]);// 并查集中的递归与路径压缩}return p[x];}int res =0;// 存储最小生成树经过的路程,也就是走过一遍的最小路程数int count =0;// 记录集合中的边数,之所以增加这个变量,是因为并不能for(int i =0; i < n; i++){// 此处是初始化每个点为一个集合,为了后面合并做准备
p[i]= i;// 满足根节点 p[x] = x 条件}for(int i =0; i < m; i++){
u = in.nextInt();
v = in.nextInt();
w = in.nextInt();
edges.add(newEdge(u, v, w));// 将边加入队列中,并做好排序}for(int i =0; i < m; i++){Edge temp = edges.poll();// 取出首节点,也就是最小的边int a = temp.a;int b = temp.b;int ww = temp.w;
a =findRoot(a);// 找到点a的根节点
b =findRoot(b);// 找到点b的根节点/所在集合if(a != b){// 两者没有连通,也就是没有边通路
p[a]= b;// 将其中一个集合并入另一个集合
res += ww;// 累加两点之间的距离
count++;// 判断走过了多少条边}}classEdgeimplementsComparable<Edge>{int a;int b;int w;publicEdge(int x,int y,int z){this.a = x;this.b = y;this.w = z;}publicintcompareTo(Edge other){// 此处是为了在优先队列中实现排序,也就实现了Comparable接口returnInteger.compare(this.w, other.w);}}
```cpp
// C++语言实现,此处是yxc实现int n, m;// n是点数,m是边数int p[N];// 并查集的父节点数组
struct Edge// 存储边{int a, b, w;
bool operator<(constEdge&W)const{return w <W.w;}}edges[M];intfind(int x)// 并查集核心操作{if(p[x]!= x) p[x]=find(p[x]);return p[x];}intkruskal(){sort(edges, edges + m);for(int i =1; i <= n; i ++) p[i]= i;// 初始化并查集int res =0, cnt =0;for(int i =0; i < m; i ++){int a = edges[i].a, b = edges[i].b, w = edges[i].w;
a =find(a), b =find(b);if(a != b)// 如果两个连通块不连通,则将这两个连通块合并{
p[a]= b;
res += w;
cnt ++;}}if(cnt < n -1)return INF;return res;}
三、例题题解
// java题解实现importjava.util.*;publicclassMain{staticintN=100010;staticint n,m;staticint u,v,w;// 使用并查集判断每个节点的归属集合// p代表点 1 ~ n 的父节点是什么staticint[] p =newint[N];// 查询节点 x 的根节点(只有根节点才可以满足p[x] = x)// 根节点的p[x]代表的就是集合本身编号staticintfindRoot(int x){if(p[x]!= x){
p[x]=findRoot(p[x]);// 并查集中的递归与路径压缩}return p[x];}publicstaticvoidmain(String[] args){Scanner in =newScanner(System.in);// 使用优先队列进行边的存储,在添加过程中实现边添加边排序// 当然此处实际上也可以使用 Edge 数组进行存储PriorityQueue<Edge> edges =newPriorityQueue<Edge>();
n = in.nextInt();
m = in.nextInt();int res =0;// 存储最小生成树经过的路程,也就是走过一遍的最小路程数int count =0;// 记录集合中的边数,之所以增加这个变量,是因为并不能for(int i =0; i < n; i++){// 此处是初始化每个点为一个集合,为了后面合并做准备
p[i]= i;// 满足根节点 p[x] = x 条件}for(int i =0; i < m; i++){
u = in.nextInt();
v = in.nextInt();
w = in.nextInt();
edges.add(newEdge(u, v, w));// 将边加入队列中,并做好排序}for(int i =0; i < m; i++){Edge temp = edges.poll();// 取出首节点,也就是最小的边int a = temp.a;int b = temp.b;int ww = temp.w;
a =findRoot(a);// 找到点a的根节点
b =findRoot(b);// 找到点b的根节点/所在集合if(a != b){// 两者没有连通,也就是没有边通路
p[a]= b;// 将其中一个集合并入另一个集合
res += ww;// 累加两点之间的距离
count++;// 判断走过了多少条边}}if(count !=(n -1)){// 没有走过 n-1 条边,也就意味着没有全部连接的通路,也就没有最小生成树System.out.println("impossible");}else{System.out.println(res);}}}classEdgeimplementsComparable<Edge>{int a;int b;int w;publicEdge(int x,int y,int z){this.a = x;this.b = y;this.w = z;}publicintcompareTo(Edge other){// 此处是为了在优先队列中实现排序,也就实现了Comparable接口returnInteger.compare(this.w, other.w);}}
Floyd算法主要内容 一、基本思路1、算法原理2、基本思路3、注意 二、Java、C语言模板实现三、例题题解 一、基本思路
1、算法原理 遍历每条边,通过比较进行路径更新——暴力 解决多源最短路问题,求解 i 点到 j 点的最短距离 f [ i, j, k] 表示从 i 走…