hdu 5627 按位于最大生成树

来源:互联网 发布:linux echo 不换行 编辑:程序博客网 时间:2024/05/23 16:53

我们贪心的从大到小枚举每一个位,如果一个位能取当且仅当所有权值这个位不为0的边能形成一棵生成树。

是否能形成生成树我们套用kruskal算法中用到的并差集可以高效实现。


#include<iostream>#include<cstdio>#include<cstdlib>#include<vector>#include<cmath>#include<string>#include<algorithm>#include<set>#include<map>#include<cstring>#include<queue>#include<stack>#include<list>using namespace std;typedef long long ll;const int MAXN=300000+5;int x[MAXN],y[MAXN],w[MAXN];int fa[MAXN];int getfa(int x){    return (!fa[x])?x: (fa[x]=getfa(fa[x]) );}int main(){int T;scanf("%d",&T);while(T--){        int n,m;        scanf("%d%d",&n,&m);        for(int i=1;i<=m;i++){            scanf("%d%d%d",&x[i],&y[i],&w[i]);        }        int ans=0;        for(int i=30;i>=0;i--){            ans+=(1<<i);            for(int j=0;j<=n;j++){                fa[j]=0;            }            int cnt=0;            for(int j=1;j<=m;j++){                if( (w[j]&ans)==ans ){                    int fx=getfa( x[j] );                    int fy=getfa( y[j] );                    if( fx==fy )continue;                    fa[ fx ]=fy;                    cnt++;                }            }            if(cnt!=n-1)ans-=(1 << i);        }        printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击