Clarke and MST
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 421 Accepted Submission(s): 233
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.
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.
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问题描述克拉克是一名人格分裂患者。某一天克拉克变成了一名图论研究者。 他学习了最小生成树的几个算法,于是突发奇想,想做一个位运算and的最大生成树。 一棵生成树是由n−1条边组成的,且n个点两两可达。一棵生成树的大小等于所有在生成树上的边的权值经过位运算and后得到的数。 现在他想找出最大的生成树。输入描述第一行是一个整数T(1≤T≤5),表示数据组数。 每组数据第一行是两个整数n,m(1≤n,m≤300000),分别表示点个数和边个数。其中n,m>100000的数据最多一组。 接下来m行,每行3个整数x,y,w(1≤x,y≤n,0≤w≤109),表示x,y之间有一条大小为w的边。输出描述每组数据输出一行一个数,表示答案。若不存在生成树,输出0。
输入样例1 4 5 1 2 5 1 3 3 1 4 2 2 3 1 3 4 7输出样例1#include<stdio.h> #include<string.h> #include<algorithm> #define ING 0x3f3f3f3f #define ll long long #define N 300010 using namespace std; struct zz { int u; int v; int w; }p[N]; int f[N]; int n,m; int find(int x) { return x==f[x]?x:f[x]=find(f[x]); } int judge(int x) { int i,j; for(i=1;i<=n;i++) f[i]=i; for(i=0;i<m;i++) { if((p[i].w&x)==x)//如果加入第i条边后不影响结果,则将这条边加入这棵树 { int fx=find(p[i].u); int fy=find(p[i].v); if(fx!=fy) f[fx]=fy; } } int cnt=0,k=find(1); for(i=2;i<=n;i++)//判断加入进去的边是否组成一颗树。 if(find(i)!=k) return 0; return 1; } int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<m;i++) scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w); int ans=0; for(i=31;i>=0;i--)//枚举所有答案 { int tmp=ans|(1<<i); if(judge(tmp)) ans=tmp; } printf("%d\n",ans); } return 0; }