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 }
官方题解:


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 }