Hdoj 3367 Pseudoforest

来源:互联网 发布:阿里云手机验证码 编辑:程序博客网 时间:2024/06/05 18:00

题目传送门

题意:     求出一个最大的子图(子图的每个连通分量最多有一个环)解题方法:  用kruskal算法求出最大生成树  不过要判断是否有环  2树合并时 :若2个子树都有环不能合并 只有一个有环可以合并 但合并后的树有环 若2个子树都没环直接合并
#include<cstdio>#include<cstring>#include<cmath>#include<cctype>#include<iostream>#include<algorithm>using namespace std;const int maxn=10010;int vis[maxn],fa[maxn];struct node{   int u,v,w;   friend bool operator<(const node &a,const node &b)   {       return a.w>b.w;   }}E[10*maxn];int n,m;int Find(int x){    if(x==fa[x])        return x;    else        return fa[x]=Find(fa[x]);}int Union(int x,int y){   int fx=Find(x);   int fy=Find(y);   if(fx==fy)   {       if(!vis[fx])       {           vis[fx]=1;           return 1;       }       return 0;   }   if(vis[fx]&&vis[fy])return 0;   if(vis[fx])      fa[fy]=fx;   else      fa[fx]=fy;   return 1;}int main(){    while(~scanf("%d%d",&n,&m))    {        if(n==0&&m==0)            return 0;        for(int i=0;i<=n;i++)            fa[i]=i;        for(int i=0;i<m;i++)        {            scanf("%d%d%d", &E[i].u,&E[i].v,&E[i].w);        }        sort(E,E+m);        int ans=0;        memset(vis,0,sizeof(vis));        for(int i=0;i<m;i++)        {            int u=E[i].u;            int v=E[i].v;            int w=E[i].w;            if(Union(u,v))                ans+=w;        }        printf("%d\n",ans);    }    return 0;}#include<cstdio>#include<cstring>#include<cmath>#include<cctype>#include<iostream>#include<algorithm>using namespace std;const int maxn=10010;int vis[maxn],fa[maxn];struct node{   int u,v,w;   friend bool operator<(const node &a,const node &b)   {       return a.w>b.w;   }}E[10*maxn];int n,m;int Find(int x){    if(x==fa[x])        return x;    else        return fa[x]=Find(fa[x]);}int Union(int x,int y){   int fx=Find(x);   int fy=Find(y);   if(fx==fy)   {       if(!vis[fx])       {           vis[fx]=1;           return 1;       }       return 0;   }   if(vis[fx]&&vis[fy])return 0;   if(vis[fx])      fa[fy]=fx;   else      fa[fx]=fy;   return 1;}int main(){    while(~scanf("%d%d",&n,&m))    {        if(n==0&&m==0)            return 0;        for(int i=0;i<=n;i++)            fa[i]=i;        for(int i=0;i<m;i++)        {            scanf("%d%d%d", &E[i].u,&E[i].v,&E[i].w);        }        sort(E,E+m);        int ans=0;        memset(vis,0,sizeof(vis));        for(int i=0;i<m;i++)        {            int u=E[i].u;            int v=E[i].v;            int w=E[i].w;            if(Union(u,v))                ans+=w;        }        printf("%d\n",ans);    }    return 0;}
0 0