标签:des style blog class code java
Time Limit: 10000/5000 MS
(Java/Others) Memory Limit: 65536/65536 K
(Java/Others)
Total Submission(s): 1526 Accepted
Submission(s): 580
伪森林:
题意为有一个伪森林,即森林里的每棵树最多有一个环。
这题还算是不错的,最小生成树小变形,要用kruskal算法,边的排序要按值大到小排。
排完序后就可以按kruskal的做法做了,不过要多作一个circle[]数组来记录每棵树环的情况,如果该树有一个环了就不能再加环,并且如果一条边有两个点一个属于有环树,一个不属于有环树,那么并查集并的时候要讲第二个点并到第一个点中,这样可以避免多个环的情况。思路清晰后还是挺简单的。
1 //546MS 1464K 1096 B G++ 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #define N 10005 6 struct node{ 7 int u,v,d; 8 }p[10*N]; 9 int set[N]; 10 int circle[N]; 11 int n,m; 12 int cmp(const void*a,const void*b) 13 { 14 return (*(node*)b).d-(*(node*)a).d; 15 } 16 int find(int x) 17 { 18 if(set[x]!=x) set[x]=find(set[x]); 19 return set[x]; 20 } 21 int kruskal() 22 { 23 int ans=0; 24 for(int i=0;i<m;i++){ 25 int tu=find(p[i].u); 26 int tv=find(p[i].v); 27 if(tu==tv){ 28 if(!circle[tu]){ 29 circle[tu]=1; 30 ans+=p[i].d; 31 } 32 continue; 33 } 34 if(circle[tu] && circle[tv]) continue; 35 if(circle[tu]) set[tv]=tu; 36 else set[tu]=tv; 37 ans+=p[i].d; 38 } 39 return ans; 40 } 41 int main(void) 42 { 43 while(scanf("%d%d",&n,&m)!=EOF&&(n+m)) 44 { 45 for(int i=0;i<=n;i++) set[i]=i; 46 memset(circle,0,sizeof(circle)); 47 for(int i=0;i<m;i++){ 48 scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].d); 49 } 50 qsort(p,m,sizeof(p[0]),cmp); 51 printf("%d\n",kruskal()); 52 } 53 }
hdu 3367 Pseudoforest (最小生成树),布布扣,bubuko.com
标签:des style blog class code java
原文地址:http://www.cnblogs.com/GO-NO-1/p/3715613.html