题目链接:点我啊╭(╯^╰)╮
题目大意:
求第 k k k 小团
解题思路:
优先队列暴力枚举每个最小团
关键在于处理重复的情况
对于每种情况,只对最后一个 1 1 1 出现的位置之后加点
也就是新增点要在当前团的最后一个点之后
时间复杂度: O ( k ? n ? l o g V ? b i t s e t < 100 > ) O(k \cdot n \cdot logV \cdot bitset<100>) O(k?n?logV?bitset<100>)
核心:第 k k k 小团模板
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 1e9 + 7;
const int maxn = 1e2 + 10;
int n, k, w[maxn];
bitset <maxn> mp[maxn], t;
char s[maxn];struct Node{ll v;bitset <maxn> u;friend bool operator < (Node A, Node B){return A.v > B.v;}
} p;
priority_queue <Node> q;int main() {scanf("%d%d", &n, &k);for(int i=0; i<n; i++) scanf("%d", w+i);for(int i=0; i<n; i++){scanf("%s", s);int len = strlen(s);for(int j=0; j<len; j++)if(s[j]=='1') mp[i][j] = 1; }q.push({0, t});while(q.size()){p = q.top();q.pop();k--;if(k==0){printf("%lld", p.v);return 0;}int pos = 0;for(int i=0; i<n; i++) if(p.u[i]) pos = i + 1;for(int i=pos; i<n; i++){if((mp[i] & p.u) == p.u){p.u[i] = 1;q.push({p.v + w[i], p.u});p.u[i] = 0;}}}puts("-1");
}