您被分配设计广泛区域中某些点之间的网络连接。您将获得该区域中的一组点,以及可连接成对点的电缆的一组可能路线。对于两点之间的每条可能路线,您将获得连接该路线上的点所需的电缆长度。请注意,两个给定点之间可能存在许多可能的路径。假设给定的可能路线(直接或间接)连接该区域中的每两个点。
您的任务是为该区域设计网络,以便在每两个点之间存在连接(直接或间接)(即,所有点都是互连的,但不一定是通过直接电缆),并且总长度为用过的电缆很小。输入输入文件由许多数据集组成。每个数据集定义一个必需的网络。集合的第一行包含两个整数:第一行定义给定点的数量P,第二行定义点之间给定路径的数量R. 以下R行定义了点之间的给定路线,每条线给出三个整数:前两个数字标识点,第三个给出路线的长度。数字用空格分隔。仅给出一个数字P = 0的数据集表示输入的结束。数据集用空行分隔。
最大点数为50.给定路线的最大长度为100.可能的路线数量不受限制。节点用1和P(含)之间的整数标识。两个点i和j之间的路线可以给出为ij或j i。
产量对于每个数据集,在单独的行上打印一个数字,该行显示用于整个设计网络的电缆的总长度。样本输入
1 0
2 3
1 2 37
2 1 17
1 2 68
3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32
5 7
1 2 5
2 3 7
2 4 8
4 5 11
3 5 10
1 5 6
4 2 12
0样本输出
0
17
16
26
解题思路:要连接所有的线,又要最短,这就需要最小生成树的概念。
现将短的路径选出来,这就需要排序,然后再判断是否有回路,用并查集检查。最后将所选边加起来。因为无回路的树n个点有n-1条边,所以到n-1退出。
#include<stdio.h>
int a[5000];
struct edge
{
int a;
int b;
int c;
};
struct edge e[5000];
void quicksort(int left,int right)
{
int i,j;
struct edge t;
i=left;
j=right;
if(i>j)return ;
while(i!=j)
{
while(i<j&&e[j].c>=e[left].c)
j--;
while(i<j&&e[i].c<=e[left].c)
i++;
if(i<j)
{
t=e[i];
e[i]=e[j];
e[j]=t;
}
}
t=e[i];
e[i]=e[left];
e[left]=t;
quicksort(left,i-1);
quicksort(i+1,right);
return ;
}
int f(int v)
{
if(a[v]==v)return v;
else
{
a[v]=f(a[v]);
return a[v];
}
}
int getf(int u,int v)
{
int t1,t2;
t1=f(u);
t2=f(v);
if(t1!=t2)
{
a[t2]=t1;
return 1;
}
return 0;
}
int main()
{
int sum,i,j,p,r,flag;
while(scanf("%d",&p)!=EOF)
{
if(p==0)break;
sum=0;
flag=0;
scanf("%d",&r);
for(i=1;i<=p;i++)
a[i]=i;
for(i=1;i<=r;i++)
{
scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
}
quicksort(1,r);
for(i=1;i<=r;i++)
{
if(getf(e[i].a,e[i].b))
{
sum+=e[i].c;
flag++;
}
if(flag==p-1)
break;
}
printf("%d\n",sum);
}
return 0;
}