hdu 5627 Clarke and MST(最大 生成树)

Problem Description
Clarke is a patient with multiple personality disorder. One day he turned into a learner of graph theory.  He learned some algorithms of minimum spanning tree. Then he had a good idea, he wanted to find the maximum spanning tree with bit operation AND.  A spanning tree is composed by n−1 edges. Each two points of n points can reach each other. The size of a spanning tree is generated by bit operation AND with values of n−1 edges.  Now he wants to figure out the maximum spanning tree.
 

 

Input
The first line contains an integer T(1≤T≤5), the number of test cases.  For each test case, the first line contains two integers n,m(2≤n≤300000,1≤m≤300000), denoting the number of points and the number of edge respectively. Then m lines followed, each line contains three integers x,y,w(1≤x,y≤n,0≤w≤109), denoting an edge between x,y with value w.  The number of test case with n,m>100000 will not exceed 1. 
 

 

Output
For each test case, print a line contained an integer represented the answer. If there is no any spanning tree, print 0.
 

 

Sample Input
1 4 5 1 2 5 1 3 3 1 4 2 2 3 1 3 4 7
 

 

Sample Output
1
 

 

Source
 


首先贴上自己的写法,虽然不是很正宗的做法

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<math.h>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<bitset>
11 #include<map>
12 #include<vector>
13 #include<stdlib.h>
14 #include <stack>
15 using namespace std;
16 #define PI acos(-1.0)
17 #define max(a,b) (a) > (b) ? (a) : (b)  
18 #define min(a,b) (a) < (b) ? (a) : (b)
19 #define ll long long
20 #define eps 1e-10
21 #define MOD 1000000007
22 #define N 300006
23 #define M 300006
24 #define inf 1e12
25 struct Node{
26     int x,y;
27     int cost;
28 }edge[M];
29 int n,m;
30 int fa[N];
31 void init(){
32     for(int i=0;i<N;i++){
33         fa[i]=i;
34     }
35 }
36 int find(int x){
37     return fa[x]==x?x:fa[x]=find(fa[x]);
38 }
39 bool cmp(Node a,Node b){
40     return a.cost>b.cost;
41 }
42 int main()
43 {
44     int t;
45     scanf("%d",&t);
46     while(t--){
47         scanf("%d%d",&n,&m);
48         init();
49         for(int i=0;i<m;i++){
50             int a,b,c;
51             scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].cost);
52         }
53         sort(edge,edge+m,cmp);
54         int flag=1;
55         int ans;
56         int num=n-1;
57         for(int i=0;i<m;i++){
58             int root1=find(edge[i].x);
59             int root2=find(edge[i].y);
60             if(root1!=root2){
61                 if(flag){
62                     ans=edge[i].cost;
63                     flag=0;
64                 }else{
65                     ans&=edge[i].cost;
66                 }
67                 fa[root1]=root2;
68                 num--;
69             }
70         }
71         if(num!=0){
72             printf("0\n");
73         }
74         else{
75             printf("%d\n",ans);
76         }
77     }
78         
79     
80     return 0;
81 }
View Code


官方题解:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N =  300000 + 10;
 7 
 8 struct Edge{
 9     int from,to,dis;
10 }a[N],b[N];
11 int fa[N];
12 int find(int x){
13     if(x==fa[x]) return x;
14     return fa[x] = find(fa[x]);
15 }
16 int tmp;
17 bool solve(int pos, Edge *a, int n, int m){
18     for(int i=1;i<=n;++i)
19         fa[i] = i;
20     int cnt = 0;
21     tmp = 0;
22     for(int i=1;i<=m;++i){
23         if(((a[i].dis>>pos)&1)==0)
24             continue;
25         
26         int fu = find(a[i].from);
27         int fv = find(a[i].to);
28         if(fu!=fv){
29             if(cnt==0)
30                 tmp = a[i].dis;
31             else
32                 tmp &= a[i].dis;
33             
34             fa[fu] = fv;
35             cnt++;
36             if(cnt==n-1)
37                 return true;
38         }
39     }
40     return false;
41 }
42 int main() {
43     
44     int t,n,m;
45     scanf("%d",&t);
46     while(t--){
47         scanf("%d%d",&n,&m);
48         
49         for(int i=1;i<=m;++i){
50             scanf("%d%d%d",&a[i].from,&a[i].to,&a[i].dis);
51         }
52         int ans = 0;
53         for(int i=30;i>=0;--i){
54             if(solve(i,a,n,m)){
55                 ans = tmp;
56                 int mm = 0;
57                 for(int i=1;i<=m;++i){
58                     if((a[i].dis>>i)&1)
59                         b[++mm] = a[i];
60                 }
61                 m = mm;
62                 for(int i=1;i<=m;++i)
63                     a[i] = b[i];
64             }
65         }
66         cout<<ans<<endl;
67     }
68     return 0;
69 }
View Code

 

posted @ 2016-02-13 21:56  UniqueColor  阅读(551)  评论(0)    收藏  举报