求连通全图的最短路径 贪心大法
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
题目地址 还是畅通工程
题解思路
在并查集的基础上加上了最短路径合的求解 思路是将所有路的长度进行排序先将长度低的路连接起来 这样便是最终的答案 (贪心大法)
核心代码
bool cmp(node a,node b)//对结构体排序方法的定义 我不太会用
{
return a.w<b.w;
}
sort(arr+1,arr+1+m,cmp); //对存储的路径按路径的长度大小进行排序
for(int i=1;i<=m;i++)
{
if(u(arr[i].x,arr[i].y)) //判断能否连接
{
ant++; //记录连接的个数
ans+=arr[i].w; //累加答案
}
if(ant==n-1) //优化代码 当全部连 通时就是答案
break;
}
并查集代码
int find2(int x) //查找父节点
{
while(x!=a[x])
x=a[x];
return x;
}
int u(int x,int y) //父节点不同联合
{
int fx=find2(x);
int fy=find2(y);
if(fx!=fy)
{
a[fy]=fx;
return 1;
}
return 0;
}
AC代码
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
struct node{
int x,y,w;
}arr[5001];
int a[101];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find2(int x)
{
while(x!=a[x])
x=a[x];
return x;
}
int u(int x,int y)
{
int fx=find2(x);
int fy=find2(y);
if(fx!=fy)
{
a[fy]=fx;
return 1;
}
return 0;
}
int main ()
{
int n,m;
scanf("%d",&n);
while(n!=0)
{
int ans=0,ant=0;
m=n*(n-1)/2;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&arr[i].x,&arr[i].y,&arr[i].w);
for(int i=1;i<=n;i++)
a[i]=i;
sort(arr+1,arr+1+m,cmp);
for(int i=1;i<=m;i++)
{
if(u(arr[i].x,arr[i].y)) //
{
ant++;
ans+=arr[i].w;
}
if(ant==n-1)
break;
}
printf("%d\n",ans);
scanf("%d",&n);
}
return 0;
}