Network POJ 1861 ZOJ 1542 Kruskal算法 提问方式有点变化而已
和ZOJ 1203解法一样,不赘述,我都直接复制的代码修改了一下
贴代码:
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #define MAXN 1020 6 #define MAXM 15020 7 using namespace std; 8 int n,m; //n为顶点个数,m为边数 9 struct ArcNode 10 { 11 int u,v; //一条边的起点和终点 12 int w; //边的权值 13 bool operator <(const ArcNode & other) const 14 { 15 if(w < other.w) return true; 16 else return false; 17 }; 18 } edge[MAXM]; //存边 19 int parent[MAXN]; //用于并查集 20 int l[MAXN]; 21 int Find(int x) 22 { 23 int s; 24 for(s = x; parent[s] >= 0; s = parent[s]); 25 while(s != x) 26 { 27 int temp = parent[x]; 28 parent[x] = s; 29 x = temp; 30 } 31 return s; 32 } 33 void Union(int x,int y) 34 { 35 int r1 = Find(x); 36 int r2 = Find(y); 37 int temp = parent[r1] +parent[r2];//两根结点所带结点的总数 38 if(parent[r1] > parent[r2]) 39 { 40 parent[r1] = r2; 41 parent[r2] = temp; 42 } 43 else 44 { 45 parent[r2] = r1; 46 parent[r1] = temp; 47 } 48 } 49 void Kruskal() 50 { 51 int i; 52 for(i=1; i <= n; i++) 53 parent[i] = -1; 54 int num =0; 55 sort(edge,edge+m); 56 for(i=0; i<m; i++) 57 { 58 int u = edge[i].u; 59 int v = edge[i].v; 60 if(Find(u) != Find(v)) 61 { 62 Union(u,v); 63 l[num++] = i; 64 } 65 if(num >= n-1) break; 66 } 67 } 68 int main() 69 { 70 // freopen("in.cpp","r",stdin); 71 int i; 72 while(~scanf("%d%d",&n,&m)) 73 { 74 for(i=0; i<m; i++) 75 { 76 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); 77 } 78 Kruskal(); 79 printf("%d\n%d\n",edge[l[n-2]].w,n-1); 80 for(i =0; i<n-1; i++) 81 printf("%d %d\n",edge[l[i]].u,edge[l[i]].v); 82 } 83 return 0; 84 }