先上题目
还是畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19536 Accepted Submission(s): 8687
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
这一题是最小生成树,数据量不大,可以用邻接矩阵来保存信息,算法的话用Prim或者Kruskal都可以,但是如果用邻接矩阵的话时间复杂度会大一点,这里我用了Kruskal算法。用了优先队列并查集辅助。因为担心对出现重边,考虑到遍历查找的速度,所以用了矩阵,反正数据也不大。
上代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #define MAX (100+10) 5 #define INF 100000000 6 using namespace std; 7 8 int N[MAX],p[MAX],rank[MAX],map[MAX][MAX]; 9 10 typedef struct 11 { 12 int a,b; 13 int l; 14 }road; 15 16 struct cmp 17 { 18 bool operator() (road x,road y) 19 { 20 return x.l>y.l; 21 } 22 }; 23 24 priority_queue<road,vector<road>,cmp> q; 25 26 void makeset(int n) 27 { 28 int i; 29 for(i=1;i<=n;i++) 30 { 31 p[i]=i; 32 rank[i]=0; 33 } 34 } 35 36 int findset(int x) 37 { 38 return x==p[x] ? x : findset(p[x]); 39 } 40 41 bool unionset(int x,int y) 42 { 43 x=findset(x); 44 y=findset(y); 45 if(x==y) return 0; 46 if(rank[x]>rank[y]) p[y]=x; 47 else 48 { 49 p[x]=y; 50 if(rank[x]==rank[y]) rank[y]++; 51 } 52 return 1; 53 } 54 55 int ku(int n) 56 { 57 int count,length; 58 road r; 59 count=0; 60 length=0; 61 while(count<n && !q.empty()) 62 { 63 r=q.top(); 64 q.pop(); 65 if(unionset(r.a,r.b)) 66 { 67 length+=r.l; 68 count++; 69 } 70 } 71 return length; 72 } 73 74 int main() 75 { 76 int n,m,i,length; 77 road r; 78 //freopen("data.txt","r",stdin); 79 while(scanf("%d",&n),n) 80 { 81 memset(map,0,sizeof(map)); 82 m=n*(n-1)/2; 83 makeset(n); 84 for(i=1;i<=m;i++) 85 { 86 scanf("%d %d %d",&r.a,&r.b,&r.l); 87 if(map[r.a][r.b]==0 || map[r.a][r.b]>r.l) 88 { 89 map[r.a][r.b]=r.l; 90 map[r.b][r.a]=r.l; 91 } 92 } 93 for(r.a=1;r.a<=n;r.a++) 94 { 95 for(r.b=r.a+1;r.b<=n;r.b++) 96 { 97 if(map[r.a][r.b]!=0) 98 { 99 r.l=map[r.a][r.b]; 100 q.push(r); 101 } 102 } 103 } 104 length=ku(n); 105 printf("%d ",length); 106 } 107 return 0; 108 }