【ybtoj 高效进阶 3.2】【最小生成树】 公路建设
题目
解题思路
这道题恶心在时间复杂度
Kruskal会比prim的时间复杂度低
Kruskal是一种贪心
我们只需要维护边权从小到大
然后跑一遍并查集
求出当前的最小花费
如果不能覆盖所有城市,输出0
代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct lzf{
int x,y,c;
}a[20020];
int n,m,top,fa[20200];
double tot;
int find(int w)
{
if (fa[w]==w) return w;
else return fa[w]=find(fa[w]);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].c);
for (int j=i;j>1;j--)
if (a[j].c<a[j-1].c)
swap(a[j],a[j-1]); //冒泡维护
tot=0;
top=0;
for (int j=1;j<=n;j++)
fa[j]=j; //一开始,自己单独一个集合
for (int j=1;j<=i;j++)
{
int xx=find(a[j].x),yy=find(a[j].y);
if (xx!=yy)
{
fa[yy]=xx;
tot+=(a[j].c*1.0)/2.0;
top++;
if (top==n-1) break;
}
} //Kruskal
if (top==n-1)
printf("%0.1f\n",tot);
else printf("0\n");
}
return 0;
}