首页 > 代码库 > HDU 3367 Pseudoforest
HDU 3367 Pseudoforest
【原题】
http://acm.hdu.edu.cn/showproblem.php?pid=3367
【题意】
给出一张图,求最大生成树。要求每一个连通块上只能有一个环。
【分析】
对于Kruskal来说,最小/最大生成树只是改变一下排序顺序即可。这里需要另外注意添加的就是对环的判断了:
如果两个节点不在同一棵树内,且分别不成环,则可合并;
如果两个节点在同一棵树内,但是未成环,则加上这条边之后将成环;
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 6 using namespace std; 7 8 typedef struct nod 9 {10 int x,y,c;11 } node;12 node a[100010];13 14 bool op(node a,node b)15 {16 return a.c>b.c;17 }18 19 int father[10010];20 bool flag[10010];21 22 void clean_father(int n)23 {24 for (int i=0;i<n;i++) father[i]=i;25 } 26 27 int getfather(int x)28 {29 if (father[x]!=x) father[x]=getfather(father[x]);30 return father[x];31 }32 33 void link(int x,int y)34 {35 father[getfather(x)]=getfather(y);36 } 37 38 int main()39 {40 int n,m;41 while (scanf("%d%d",&n,&m))42 {43 if (n==0&&m==0) break;44 45 for (int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].c);46 sort(&a[1],&a[m+1],op);47 48 clean_father(n);49 memset(flag,0,sizeof(flag));50 int ans=0;51 for (int i=1;i<=m;i++)52 if (getfather(a[i].x)!=getfather(a[i].y))53 {54 if (!(flag[getfather(a[i].x)]&&flag[getfather(a[i].y)]))55 {56 57 if (flag[getfather(a[i].x)]||flag[getfather(a[i].y)])58 {59 flag[getfather(a[i].x)]=true;60 flag[getfather(a[i].y)]=true;61 }62 link(a[i].x,a[i].y);63 ans+=a[i].c;64 }65 } else 66 if (!flag[getfather(a[i].x)])67 {68 ans+=a[i].c;69 flag[getfather(a[i].x)]=true;70 }71 72 printf("%d\n",ans);73 }74 75 return 0;76 }
HDU 3367 Pseudoforest
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。