Program4_A
来源:互联网 发布:网络评论引导员 编辑:程序博客网 时间:2024/06/06 00:14
我现在做的是第四专题编号为1001的试题,具体内容如下所示:
Problem A
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 24 Accepted Submission(s) : 16
30 990 692990 0 179692 179 011 2
179
在修建之前有的村庄之间有已经建造的道路,求使所有村庄连在一起需要再建造的道路的最小值
解题思路:
最小生成树的题目,主要是并查集的运用,将关系矩阵转化为经典的顶点和边的模型,而且长短已知,只需要判断什么时候统计和累加就可以了,因为已经给出了某些已知的路径,那么就先把这些路径涉及的端点先合并,并且在合并的时候统计有效的道路数量(不形成环),然后下面就是遍历查找,直到 n-1 (n个端点)条边全部找到,最小生成树已经生成,输出相应的累加数值....
编写代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int per[10005],n,kase,cnt;
struct road
{
int a,b;
int len;
}x[10005];
void init()
{
for(int i=1;i<=n;++i)
{
per[i]=i;
}
}
int find(int x)
{
int r=x;
while(r!=per[r])
{
r=per[r];
}
int i=x,j;
while(i!=r)
{
j=per[i];
per[i]=r;i=j;
}
return r;
}
void join(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
per[fy]=fx;
++cnt;
kase=1;
}
}
int cmp(road a,road b)
{
return a.len<b.len;
}
int main()
{
int a,b,i,j,c,sum;
while(~scanf("%d",&n))
{
init();
cnt=c=0;
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
scanf("%d",&a);
if(i!=j)
{
x[c].a=i+1;
x[c].b=j+1;
x[c].len=a;
++c;
}
}
}
int m,sum=0;
scanf("%d",&m);
for(i=0;i<m;++i)
{
scanf("%d%d",&a,&b);
join(a,b);
}
sort(x,x+c,cmp);
for(i=0;cnt<n-1;++i)
{
kase=0;
join(x[i].a,x[i].b);
if(kase)
{
sum+=x[i].len;
}
}
printf("%d\n",sum);
}
return 0;
}