您的位置:首页 > 其它

hdoj Clarke and MST 5627(求位运算and后得到的最大生成树)(并查集&位运算)好题

2016-02-28 19:34 465 查看

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


[align=left]Problem Description[/align]
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.
 

[align=left]Input[/align]
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. 

 

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

[align=left]Sample Input[/align]

1
4 5
1 2 5
1 3 3
1 4 2
2 3 1
3 4 7

 

[align=left]Sample Output[/align]

1问题描述
克拉克是一名人格分裂患者。某一天克拉克变成了一名图论研究者。
他学习了最小生成树的几个算法,于是突发奇想,想做一个位运算and的最大生成树。
一棵生成树是由n-1n−1条边组成的,且nn个点两两可达。一棵生成树的大小等于所有在生成树上的边的权值经过位运算and后得到的数。
现在他想找出最大的生成树。
输入描述
第一行是一个整数T(1 \le T \le 5)T(1≤T≤5),表示数据组数。
每组数据第一行是两个整数n, m(1 \le n, m \le 300000)n,m(1≤n,m≤300000),分别表示点个数和边个数。其中n, m > 100000n,m>100000的数据最多一组。
接下来mm行,每行33个整数x, y, w(1 \le x, y \le n, 0 \le w \le 10^9)x,y,w(1≤x,y≤n,0≤w≤10​9​​),表示x, yx,y之间有一条大小为ww的边。
输出描述
每组数据输出一行一个数,表示答案。若不存在生成树,输出00。
输入样例
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
;
int f
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: