Pseudoforest |
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) |
Total Submission(s): 182 Accepted Submission(s): 85 |
|
Problem Description
In graph theory, a pseudoforest is an undirected graph in which
every connected component has at most one cycle. The maximal
pseudoforests of G are the pseudoforest subgraphs of G that are not
contained within any larger pseudoforest of G. A pesudoforest is larger
than another if and only if the total value of the edges is greater than
another one’s.
|
Input
The input consists of multiple test cases. The first line of each
test case contains two integers, n(0 < n <= 10000), m(0 <= m
<= 100000), which are the number of the vertexes and the number of
the edges. The next m lines, each line consists of three integers, u, v,
c, which means there is an edge with value c (0 < c <= 10000)
between u and v. You can assume that there are no loop and no multiple
edges.
The last test case is followed by a line containing two zeros, which means the end of the input. |
Output
Output the sum of the value of the edges of the maximum pesudoforest.
|
Sample Input
3 3 0 1 1 1 2 1 2 0 1 4 5 0 1 1 1 2 1 2 3 1 3 0 1 0 2 2 0 0 |
Sample Output
3 5 |
思路:伪森林,详见维基百科,其实就是最短路变成最长路,用kruskal
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cstring> 6 #include <string> 7 #include <cstdlib> 8 using namespace std; 9 10 const int maxn=10010,maxm=100100; 11 int p[maxn],fn,fto,n,m,ans; 12 bool f[maxn]; 13 struct qq 14 { 15 int n,to,d; 16 friend bool operator < (qq a,qq b) 17 { 18 return a.d>b.d; 19 } 20 } e[maxm]; 21 22 void close() 23 { 24 exit(0); 25 } 26 27 int getfather(int k) 28 { 29 if (p[k]==k) 30 return k; 31 p[k]=getfather(p[k]); 32 return p[k]; 33 } 34 void work() 35 { 36 memset(f,false,sizeof(f)); 37 ans=0; 38 for (int i=1;i<=m;i++) 39 { 40 fn=getfather(e[i].n); 41 fto=getfather(e[i].to); 42 // printf("n:%d fn:%d to:%d fto:%d ans:%d\n",e[i].n,fn,e[i].to,fto,ans); 43 if (fn==fto) 44 { 45 if (not f[fn]) //祖先是同一个,但没有环 46 { 47 ans+=e[i].d; 48 f[fn]=true; 49 } 50 } 51 else//没有环,完全可以合并,但要注意有环的赋值 52 { 53 if (f[fn] && f[fto]) 54 continue; 55 ans+=e[i].d; 56 if (f[fn] || f[fto]) 57 { 58 f[fn]=true; 59 f[fto]=true; 60 } 61 p[fn]=fto; 62 } 63 } 64 printf("%d\n",ans); 65 } 66 67 68 void init() 69 { 70 while (scanf("%d %d",&n,&m)!=EOF) 71 { 72 if (n==0 && m==0) break; 73 for (int i=0;i<=n;i++) 74 p[i]=i; 75 for (int i=1;i<=m;i++) 76 { 77 scanf("%d %d %d",&e[i].n,&e[i].to,&e[i].d); 78 } 79 sort(e+1,e+m+1); 80 work(); 81 } 82 } 83 84 int main () 85 { 86 init(); 87 close(); 88 return 0; 89 }