zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第二场)D (bitset)

    题意:

    让你求出一张图的第(k)小团的权值。

    分析:

    这道题目相当的有意思!

    我们发现我们很难直接高效的算出一张图的第(k)小团的权值。因此,我们考虑将这个问题转化一下。我们发现,因为权值都是正数,因此如果在一个已知的团上能够再增加一个新结点形成团,那么新的团的权值必定增加。因此,我们如果从空集不断往上去增加新的结点构造成团,那么在这个过程中,权值一定是不断增加的。因此我们只需要从小到大拓展团,并将当前的团的权值丢进一个优先队列里进行维护,最后不断获取到第(k)小的权值即可。至此,我们需要考虑如何能够高效的在一个团上增加新的结点。

    如果一个结点(a_i)加入到团(S)中,还能够形成团,那么意味着(a_i)一定跟团(S)中的每一个结点都有连边。考虑到在邻接矩阵,有无边是通过(01)的状态维护,因此我们在此可以考虑用( ext{bitset})代替邻接矩阵进行优化。此时点(a_i)跟其他点的连边状态我们可以用一个( ext{bitset})(bit_1)来表示,团的状态也可以用一个( ext{bitset})(bit_2)来表示,那么,那么判断团中的结点是否跟(a_i)相连,我们只需要用(&)运算即可解决。

    如此一来,我们就可以通过(mathcal{O}(klogk))的时间复杂度解决这个问题。

    #include <bits/stdc++.h>
    #define maxn 105
    using namespace std;
    typedef  long long ll;
    struct Node{
        ll w;
        bitset<maxn>bit;
        Node(){}
        Node(ll _w,bitset<maxn> _bit){
            w=_w,bit=_bit;
        }
        bool operator <(const Node b)const{
            return b.w<w;
        }
    };
    bitset<maxn> edge[maxn];
    int n,k,a[maxn];
    char str[maxn];
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++){
            scanf("%s",str+1);
            for(int j=1;j<=n;j++){
                if(str[j]=='1')
                    edge[i].set(j);
            }
        }
        priority_queue<Node>que;
        bitset<maxn> b1;
        ll val=0;
        b1.reset();
        que.push(Node(val,b1));
        for(int i=1;i<=k;i++){
            if(que.empty()){
                puts("-1");
                return 0;
            }
            if(i==k){
                printf("%lld
    ",que.top().w);
                return 0;
            }
            b1=que.top().bit,val=que.top().w;
            que.pop();
            int z=1;//为了保证不会重复加点,我们每次从一个已经加入的点的后一个结点开始枚举新加入的结点。
            for(int j=1;j<=n;j++){
                if(b1[j]) z=j+1;
            }
            for(int j=z;j<=n;j++){
                if(b1[j]==0&&( (b1&edge[j])==b1)){
                    bitset<maxn>b2;
                    b2=b1, b2.set(j);
                    que.push(Node(val+a[j],b2));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    python模块添加
    Python 的列表排序
    python中文处理问题
    排序算法堆排序
    搜索二分搜索
    排序算法(随机)快速排序(递归)
    排序算法计数排序
    OO设计原则总结
    异常控制以及进程调度
    ubuntu12.04 alternate win7 双系统安装
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11222852.html
Copyright © 2011-2022 走看看