传送门
找第\(k\)小团。
用\(bitset\)来标记每个结点与哪些结点直接有边,然后进行\(bfs\),在判断新加入的点与现在有的点是否都有边则直接用\(bitset\)与一下即可,记得去重。
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long LL; typedef pair pLL; typedef pair pLi; typedef pair pil;; typedef pair pii; typedef unsigned long long uLL; #define lson (rt<<1),L,mid #define rson (rt<<1|1),mid + 1,R #define lowbit(x) x&(-x) #define name2str(name) (#name) #define bug printf("*********\n") #define debug(x) cout<<#x"=["< vis[105]; int w[maxn], mp[maxn][maxn]; struct node { LL val; bitset<101> has; bool operator < (const node& x) const { return val > x.val; } }nw; priority_queue q; int main() { #ifndef ONLINE_JUDGE FIN; #endif scanf("%d%d", &n, &k); for(int i = 1; i <= n; ++i) { scanf("%d", &w[i]); nw.has.set(i), nw.val = w[i]; q.push(nw); nw.has.reset(i); } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) { scanf("%1d", &mp[i][j]); if(mp[i][j]) vis[i].set(j); } } LL ans = -1; if(k == 1) { printf("0\n"); return 0; } --k; while(!q.empty()) { nw = q.top(), q.pop(); if(--k == 0) { ans = nw.val; break; } int idx = 1; for(int i = 1; i <= n; ++i) if(nw.has.test(i)) idx = i + 1; for(int i = idx; i <= n; ++i) { if(nw.has.test(i)) continue; if((vis[i] & nw.has) != nw.has) continue; nw.val += w[i]; nw.has.set(i); q.push(nw); nw.val -= w[i]; nw.has.reset(i); } } printf("%lld\n", ans); return 0; }