牛客多校第二场 D.Kth Minimum Clique(bitmask优化跑团)

小团拓展出的新团一定比大团拓展出的新团要小,因此可以使用优先队列搜索。
在寻找可拓展点的时候,可以使用位运算来优化,如果当前团的点集是找到点出边的子集,就可以拓展团。
每个团找拓展点的时候只找比最后入团的点编号大的,不回头找(回头找会拓展出重复的团)。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 105;

int n, k, w[maxn];

struct node {
    int id;
    ll val;
    bitset<maxn> u;

    friend bool operator<(node a, node b) {
        return a.val > b.val;
    }
};

bitset<maxn> g[maxn], t;
char s[maxn];

int main() {
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &w[i]);
    }
    for (int i = 1; i <= n; ++i) {
        scanf("%s", s + 1);
        for (int j = 1; j <= n; ++j) {
            g[i][j] = s[j] - '0';
        }
    }

    priority_queue<node> q;
    q.push({0, 0, t});
    while (!q.empty()) {
        node e = q.top();
        q.pop(), --k;
        if (k == 0) {
            printf("%lld\n", e.val);
            return 0;
        }
        for (int i = e.id + 1; i <= n; ++i) {
            if (e.u[i]) {
                continue;
            }
            if ((e.u & g[i]) == e.u) {
                e.u[i] = 1;
                q.push({i, e.val + w[i], e.u});
                e.u[i] = 0;
            }
        }
    }
    printf("-1\n");
    return 0;
}
发布了156 篇原创文章 · 获赞 20 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Cymbals/article/details/96766574