Pseudoforest
题目链接:Click Here~
题目分析:
就是给你一张图,要求你找出一个森林。而这个森林可以形成环,但是最多只能有一个环。所以,就想到了,对有无环和到底有几个环进行判断就可以了。
算法分析:
运用Kruscal和并查集进行类最长路的做法,模拟算法。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e4 + 5;
struct Node
{
int u,v,c;
bool operator < (const Node &a)const{
return c > a.c;
}
}node[N*10];
int n,m,fa[N],vst[N];
inline void Init()
{
for(int i = 0;i < N;++i)
fa[i] = i,vst[i] = 0;
}
int Find(int u)
{
if(u == fa[u])
return fa[u];
return fa[u] = Find(fa[u]);
}
int Kruscal()
{
int ans = 0;
for(int i = 0;i < m;++i){
int a = Find(node[i].u),b = Find(node[i].v);
if(a != b){
if(vst[a]&&vst[b]) //两棵树合并会造成两个环
continue;
if(vst[a]) //有一个环
fa[b] = a;
else if(vst[b]) //有一个环
fa[a] = b;
else //没环
fa[a] = b;
ans += node[i].c;
}else //加入后会形成一个环
{
if(vst[a]) //原本就有一个环
continue;
vst[a] = 1;
ans += node[i].c;
}
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m),(n||m))
{
Init();
for(int i = 0;i < m;++i)
scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].c);
sort(node,node+m);
printf("%d\n",Kruscal());
}
return 0;
}