题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3367
刚开始没读懂题,觉得好难好难。。。
后来看别人的博客终于懂了什么意思。。。
题目就是求一个最大的生成森林,每个连通的部分最多有一个环,求其权值最大多少?
代码如下:内附详细注释
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
/*
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
*/
int n,m;
int parent[10010];
int visit[100010];//标记父节点这个是否已经构成一个环
struct xh
{
int x,y,w;
}edge[100010];
bool emp(xh a,xh b)
{
return a.w>b.w;
}
void UFset()
{
for(int i=0;i<=n;i++)
parent[i]=i;
}
int find(int x)
{
int r=x;
while(x!=parent[x])
x=parent[x];
while(r!=x)
{
int j=parent[r];
parent[r]=x;
r=j;
}
return x;
}
void Kruskal()
{
int i,sum=0;
UFset();
memset(visit,0,sizeof(visit));
for(i=0;i<m;i++)
{
int fx=find(edge[i].x);
int fy=find(edge[i].y);
if(fx==fy&&!visit[fx])//x,y两点在一个连通图中但是不构成回路
{
visit[fx]=1;
sum+=edge[i].w;
}
else if(visit[fx]&&!visit[fy])//y点单独,x点已经在构成一个回路中,可以把y点加入这个回路中
{
parent[fy]=fx;
sum+=edge[i].w;
}
else if(!visit[fx]&&visit[fy])//x点单独,y点已经在构成一个回路中,可以把x点加入这个回路中
{
parent[fx]=fy;
sum+=edge[i].w;
}
else if(!visit[fx]&&!visit[fy])//x、y两个点都是单独的
{
parent[fx]=fy;
sum+=edge[i].w;
}
}
printf("%d\n",sum);
}
int main()
{
int i,j;
while(cin>>n>>m,n+m)
{
for(i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a<b)
swap(a,b);
edge[i].x=a;
edge[i].y=b;
edge[i].w=c;
visit[i]=0;
}
sort(edge,edge+m,emp);//从大到小排序
Kruskal();
}
return 520;
}