把所有边(按权值)排序,记第i小的边为e[i](1<= i < m)初始化MST为空初始化连通分量,让每个点自成一个独立的连通分量for(int i =0; i < m; i++) {if(e[i].u 和 e[i].v 不在同一个连通分量) { 把边e[i]加入MST 合并e[i].u和e[i].v所在的连通分量 }}
intcmp(constint i,constint j) { returnw[i] <w[j]; } //间接排序函数intfind(int x) { returnp[x] == x ? x :p[x] =find(p[x])} //并查集的findintKruskal() {int ans =0;for(int i =0; i < n; i++) p[i] = i; //初始化并查集for(int i =0; i < m; i++) r[i] = i;sort(r,r+m,cmp);for(int i =0; i < m; i++) {int e =r[i];int x =find(u[e]);//找出一个端点所在集合编号int y =find(v[e]);//找出另一个端点所在集合编号if(x != y) { //若在不同集合,合并 ans +=w[e];p[x] = y; } }return ans;}
Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。 Input 测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。 Output 对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
#include<iostream>#include<algorithm>usingnamespace std;constint maxn =105;int N,M,cnt;intu[maxn],v[maxn],w[maxn];intr[maxn],fa[maxn];boolcmp(constint r1,constint r2) {returnw[r1] <w[r2];}intfind(int x) {returnfa[x] == x ? x :fa[x] =find(fa[x]);}intKruskal() {int ans =0;for(int i =0; i < M; i++) fa[i] = i;//初始化并查集,让每个点自成一个连通分量for(int i =0; i < N; i++) r[i] = i;//存储边序号sort(r, r+N, cmp);//将边从小到大按权值排序for(int i =0; i < N; i++) {int e =r[i];int x =find(u[e]);int y =find(v[e]);if(x != y) { ans +=w[e]; cnt++;fa[x] = y; } }return ans;}intmain() {while(cin >> N >> M) { cnt =0;if(N ==0) break;for(int i =0; i < N; i++) { cin >>u[i] >>v[i] >>w[i]; }int ans =Kruskal();if(cnt != M-1) cout <<"?"<< endl;else cout << ans << endl; }return0;}
Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。 Input 测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。 当N为0时输入结束。 Output 每个测试用例的输出占一行,输出全省畅通需要的最低成本。
#include<iostream>#include<algorithm>usingnamespace std;constint maxn =5008;intfa[101];intfind(int x) {returnfa[x] == x ? x :fa[x] =find(fa[x]);}structEdge {public:int u, v, w;booloperator<(constEdge&a)const{ return w <a.w; }}E[maxn];intmain() {int N;while(scanf("%d",&N) != EOF) {int ans =0;if(N ==0) break;int M = N*(N-1)/2;for(int i =1; i <= M; ++i) {int flag;scanf("%d%d%d%d",&E[i].u,&E[i].v,&E[i].w,&flag);if(flag) E[i].w =0; }for(int i =1; i <= N; ++i) fa[i] = i;//初始化并查集,让每个点自成一个连通分量sort(E+1,E+1+M);//将边从小到大按权值排序for(int i =1; i <= M; ++i) {int x =find(E[i].u);int y =find(E[i].v);if(x != y) {fa[x] = y; ans +=E[i].w; } }printf("%d\n",ans); }return0;}
#include<iostream>#include<algorithm>usingnamespace std;constint maxm =200000;intfa[5005];//最大顶点数5000int N,M,cnt;//顶点数 边数structedge {int u,v,w;booloperator<(constedge& a) const {return w <a.w; }} E[maxm];//最大边数maxnintfind(int x) {returnfa[x] ==-1? x :fa[x] =find(fa[x]);}intKruskal() {for(int i =0; i < N; ++i) fa[i] =-1;int ans =0;sort(E,E+M);for(int i =0; i < M; ++i) {int x =find(E[i].u);int y =find(E[i].v);if(x != y) {fa[x] = y; ans +=E[i].w; cnt++; } }if(cnt == N-1) return ans;elsereturn-1;}intmain() {scanf("%d%d",&N,&M);for(int i =0; i < M; ++i) {scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w); }int ans =Kruskal();if(ans ==-1) printf("orz\n");elseprintf("%d\n",ans);return0;}