题目1017:还是畅通工程
时间限制:1 秒
内存限制:32 兆
特殊判题:否
提交:2961
解决:1483
-
题目描述:
-
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
-
输入:
-
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
-
输出:
-
对每个测试用例,在1行里输出最小的公路总长度。
-
样例输入:
-
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
-
样例输出:
-
3 5
标准的最小生成树,prim,kruskal都可以解,不多说什么了,直接上代码
prim算法
#include<iostream> #include<string> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int inf=1<<30; int sum,n; struct node { int beg,en; int length; }tree[105]; int Map[105][105]; void prim() { int pos,Min,v,i,j; node x; for(i=2;i<=n;i++) { tree[i-1].beg=1; tree[i-1].en=i; tree[i-1].length=Map[1][i]; } for(i=1;i<n;i++) { Min=tree[i].length; pos=i; for(j=i+1;j<n;j++) { if(tree[j].length<Min) { pos=j; Min=tree[j].length; } } v=tree[pos].en; x=tree[pos];tree[pos]=tree[i];tree[i]=x; for(j=i+1;j<n;j++) { if(Map[v][tree[j].en]<tree[j].length) { tree[j].length=Map[v][tree[j].en]; tree[j].beg=v; } } } } void Sum() { sum=0; for(int i=1;i<n;i++) sum+=tree[i].length; } int main() { while(cin>>n && n) { int a,b; fill(&Map[0][0],&Map[105][0],inf); for(int i=1;i<=(n*(n-1)/2);i++) { cin>>a>>b; cin>>Map[a][b]; Map[b][a]=Map[a][b]; } prim(); Sum(); cout<<sum<<endl; } return 0; }
kruskal算法#include<iostream> #include<string> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; struct edge { int beg,en; int length; }edges[10000],tree[105]; int n,sum; int cmp(edge a,edge b) { return a.length<b.length; } void read() { for(int i=0;i<(n*(n-1)/2);i++) { cin>>edges[i].beg>>edges[i].en>>edges[i].length; } } void print() { for(int i=0;i<(n*(n-1)/2);i++) { cout<<edges[i].beg<<" "<<edges[i].en<<" "<<edges[i].length<<endl; } } void kruskal() { int temp[105],k=0,flag; sort(edges,edges+n*(n-1)/2,cmp); for(int i=1;i<=n;i++) temp[i]=i; for(int i=1;i<n;i++) { while(temp[edges[k].beg]==temp[edges[k].en]) k++; tree[i]=edges[k]; flag=temp[edges[k].en]; for(int j=1;j<=n;j++) if(flag==temp[j]) temp[j]=temp[edges[k].beg]; k++; } } void Sum() { sum=0; for(int i=1;i<n;i++) sum+=tree[i].length; } int main() { while(cin>>n &&n) { read(); //print(); kruskal(); Sum(); cout<<sum<<endl; } return 0; }