http://acm.hdu.edu.cn/showproblem.php?pid=1233
题意:连接所有村子的最短路径。
分析:最小生成树。注意:双向图。嗨,表示水题不认真又wa了 3次。
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> using namespace std; #define INF 0x3f3f3f3f const int maxn = 2010; struct node{ int u,v; int w; }edges[maxn*4]; int pa[maxn]; int n,m; int x[maxn],y[maxn]; int sumweight=0; //初始化 void UFset(){ for(int i=1;i<=n;i++){ pa[i]=-1; } } //查找 int findset(int x){ int s; for(s=x;pa[s]>=0;s=pa[s]); while(s!=x){ int tmp=pa[x]; pa[x]=s; x=tmp; } return s; } //合并 void Union(int R1,int R2){ int r1=findset(R1), r2=findset(R2); int tmp=pa[r1]+pa[r2]; if(pa[r1]>pa[r2]){ pa[r1]=r2; pa[r2]=tmp; } else { pa[r2]=r1; pa[r1]=tmp; } } int cmp(const void*a,const void*b){ node aa=*(const node*)a; node bb=*(const node*)b; if(aa.w>bb.w) return 1; else return -1; } void Kruskal(){ int num=0; int u,v; UFset(); for(int i=0;i<m;i++){ u=edges[i].u; v=edges[i].v; if(findset(u)!=findset(v)){ sumweight+=edges[i].w; num++; Union(u,v); } if(num>=n-1) break; } } int main(){ //int t; //scanf("%d",&t); while(scanf("%d",&n)!=EOF){ if(n==0) break; m=n*(n-1)/2; int u,v,w; for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&w); edges[i].u=u; edges[i].v=v; edges[i].w=w; edges[i].u=v; edges[i].v=u; edges[i].w=w; } qsort(edges,m,sizeof(edges[0]),cmp); // for(int i=0;i<m;i++){ // printf("edges[i].w=%d\n",edges[i].w); // } sumweight=0; Kruskal(); printf("%d\n",sumweight); } return 0; }