传送门:hdu 2122
题目大意
判断输入的几个节点能不能组成最小生成树,如果能输出最小生成树的值,如果不能疏忽impossible
解题思路
刚开始用的prim一直WA一直WA就改为kruskal了,就kruskal果断过了!
kruskal和prim不同的是,prim主要是针对节点的,也就是把节点加入集合里面,kruskal是把边也就是权值从小到大的加入到集合里面,如果这两个边不在同一个连通分量里面,就转换为一个连通分量,最后判断是不是之后一个连通分量,如果有的话就是有最小生成树,输出数值
AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 10010;
int pre[MAXN];
int N,M;
struct Node{
int a,b,val;
}s[MAXN];
bool cmp(Node a,Node b)
{
return a.val<b.val;
}
void init()
{
for(int i=0;i<N;i++)
pre[i] = i;
}
int find(int x)
{
return (pre[x]!=x)?(pre[x] = find(pre[x])):pre[x];
}
int main()
{
while(~scanf("%d%d",&N,&M))
{
init();
for(int i=0;i<M;i++)
scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].val);
sort(s,s+M,cmp);
int amount = 0,sum = 0;
for(int i=0;i<M;i++)
{
int fx = find(s[i].a),fy = find(s[i].b);
if(fx!=fy)//判断是不是在同一个连通分量
{
pre[fx] = fy;
amount++;
sum+=s[i].val;
}
}
if(amount == N-1)
printf("%d\n\n",sum);
else
printf("impossible\n\n");
}
return 0;
}