还是畅通工程
2015-07-29 13:57
387 查看
还是畅通工程
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)Total Submission(s) : 7 Accepted Submission(s) : 2
[align=left]Problem Description[/align]
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
[align=left]Input[/align]
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。当N为0时,输入结束,该用例不被处理。
[align=left]Output[/align]
对每个测试用例,在1行里输出最小的公路总长度。
[align=left]Sample Input[/align]
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
[align=left]Sample Output[/align]
3
5
C语言程序代码
/* 解题思路:: 这是个并查集的题,基本思路就是先找出最小要修几条路,然后再找出修这几条路 的最短距离。 1、 首先定义一个结构体来存放两个村庄编号和两个村庄之间的距离。 2、将两个村庄的距离按从小到大的顺序排序。 3、运用并查集找出它们之间最少要修几条路。 4、通过对距离的排序,找出其中距离最小的。 */ #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int b[101],sum; struct zx //定义一个结构体 { int c1,c2,l; //c1为村庄1的编号,c2为村庄2的编号,l为它们之间的距离 }a[11000]; int cmp(zx a,zx b)//将村庄之间的距离按从小到大排序 { return a.l<b.l; } int find(int x) { while(b[x]!=x) x=b[x]; return x; } int marge(int x,int y,int z)// { int fx,fy; fx=find(x);fy=find(y); if(fx!=fy) sum+=z,b[fx]=fy;//如果它们不成环,将它们的距离相加(sum),最后找到最小的 } int main(){ int t,n,m,i,j,k; while(scanf("%d",&n),n) { m=n*(n-1)/2;sum=0; for(j=1;j<=n;j++) b[j]=j; for(j=0;j<m;j++) scanf("%d %d %d",&a[j].c1,&a[j].c2,&a[j].l); sort(a,a+m,cmp); for(j=0;j<m;j++) { marge(a[j].c1,a[j].c2,a[j].l); } printf("%d\n",sum); } return 0; <pre class="cpp" name="code">/*用prim解 */ #include<stdio.h> #include<string.h> #include<math.h> #define mx 0xfffffff int n,m; int g[110][110]; void prim() { int vis[110],dis[110],min,sum; int v,i,j,k; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) dis[i]=g[1][i]; dis[1]=0; vis[1]=1; for(v=1;v<n;v++) { min=mx; k=1; for(i=1;i<=n;i++) { if(!vis[i]&&dis[i]<min) { min=dis[i]; k=i; } } vis[k]=1; for(i=1;i<=n;i++) { if(!vis[i]&&dis[i]>g[k][i]) dis[i]=g[k][i]; } } sum=0; for(i=2;i<=n;i++) sum+=dis[i]; printf("%d\n",sum); return ; } int main(){ while(scanf("%d",&n),n) { int i,j,k,l; m=n*(n-1)/2; while(m--) { scanf("%d%d%d",&i,&j,&l); g[i][j]=g[j][i]=l; } prim(); } return 0; }
相关文章推荐
- 面试题30——最小的k个数
- hdu1231最大连续子序列(简单的动态规划)
- 九度OJ 玛雅人的密码
- linux ubunu中安装mysql
- IOS应用之间的跳转和数据传
- 软件项目的开发步骤(图)
- HDU5325——DP+搜索——Crazy Bobo
- Atom飞行手册翻译: 2.1 Atom中的包
- Netty百万级推送服务设计要点
- Java NIO
- PB中字符编码转换
- Oracle 表id实现自增
- BIEE初次启动密码输入错误
- 【语言-C++】MD5加密算法 32bit 16bit 源码
- Unity5中Inspector界面上的AssetBundle值设定问题
- Https流程(简单认识)
- HDUOJ 1896(优先队列)
- 写在Demo战斗系统之前,先用原型工具做套UI第二篇-人物选择界面制作
- css文字样式
- Linux中用mdadm管理软件raid