2019牛客暑期多校训练营(第二场)- Kth Minimum Clique

优先队列bfs + 状态压缩

不难想到,最小团就是空集,我们可以向这个空集里加点,来找到k小团

具体做法就是用优先队列,把权值小的团出队,为了不重复加点,我们可以记录一下最后几个被加进团的点,这样下次直接从该点之后遍历,这样就可以把所有点都遍历一次了。

用bitset来保存点连接状态可以直接判断该点是否与团的每个点相连

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
using namespace std;
typedef long long LL;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
    int ret = 0, w = 0; char ch = 0;
    while(!isdigit(ch)){
        w |= ch == '-', ch = getchar();
    }
    while(isdigit(ch)){
        ret = (ret << 3) + (ret << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -ret : ret;
}
inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }
template <typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
    A ans = 1;
    for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
    return ans;
}
const int N = 200;
int n, k, val[N];

struct Node{
    LL w;
    int s;
    bitset<105> clique;
    bool operator < (const Node &rhs) const {
        return w > rhs.w;
    }
    Node(){}
    Node(LL w, int s, bitset<105> clique): w(w), s(s), clique(clique){}
};

bitset<105> e[N];

LL solve(){
    priority_queue<Node> pq;
    int cnt = 0;
    bitset<105> raw;
    raw.reset();
    pq.push(Node(0, 0, raw));
    while(!pq.empty()){
        Node cur = pq.top(); pq.pop();
        cnt ++;
        if(cnt == k) return cur.w;
        for(int i = cur.s + 1; i <= n; i ++){
            if((e[i] & cur.clique) == cur.clique){
                bitset<105> b(cur.clique);
                b.set(i, 1);
                pq.push(Node(cur.w + val[i], i, b));
            }
        }
    }
    return -1;
}

int main(){

    n = read(), k = read();
    for(int i = 1; i <= n; i ++) val[i] = read();
    string s;
    for(int i = 1; i <= n; i ++){
        cin >> s;
        for(int j = 1; j <= n; j ++){
            e[i].set(j, s[j - 1] - '0');
        }
    }
    printf("%lld
", solve());
    return 0;
}
原文地址:https://www.cnblogs.com/onionQAQ/p/11222578.html