zoukankan      html  css  js  c++  java
  • HDU 5627 Clarke and MST &意义下最大生成树 贪心

    Clarke and MST

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5627

    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

    Hint

    题意

    让你求&意义下的最大生成树

    题解:

    贪心,我们从高位到低位贪心,如果含有这一位的边能够构成一棵树的话,我们就可以直接把其他不含有这一位的边全部去掉

    然后重复这个行为

    这个贪心显然正确啦,至于判断能否构成一颗树,就用并查集就好啦

    代码

    #include<algorithm>
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    const int maxn = 3e5+6;
    int x[maxn],y[maxn];
    int w[maxn];
    int flag[maxn];
    int fa[maxn];
    int fi(int x)
    {
        return x == fa[x]?x:fa[x]=fi(fa[x]);
    }
    int uni(int x,int y)
    {
        int p = fi(x),q = fi(y);
        if(p != q)
            fa[p]=fa[q];
    }
    int main()
    {
        int t;scanf("%d",&t);
        for(int cas=1;cas<=t;cas++)
        {
            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--)
            {
                for(int j=1;j<=n;j++)
                    fa[j]=j;
                for(int j=1;j<=m;j++)
                {
                    if(((w[j]&ans)==ans)&&(w[j]>>i&1))
                        flag[j]=1;
                    else
                        flag[j]=0;
                }
                for(int j=1;j<=m;j++)
                    if(flag[j])
                        uni(x[j],y[j]);
                int p = fi(1);
                int f = 1;
                for(int j=1;j<=n;j++)
                    if(fi(j)!=p)
                        f = 0;
                if(f)
                    ans|=(1<<i);
            }
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    Visual Studio使用技巧
    排颜色问题——数组 leetcode lintcode
    【简洁】微信为何总令人感觉如此简洁、?(一)
    字符串通信协议解析函数
    我所改造的JSocket适用于任何DELPHI版本
    缓存和字符串相互转换
    TcxDBTreeList导出EXCEL
    TcxGrid导出EXCEL
    TdxAlertWindowManager右下角HINT显示控件
    好用的编辑框布局控件TdxLayoutControl
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5188508.html
Copyright © 2011-2022 走看看