牛客第二场 D Kth Minimum Clique —— 第k小团

题目链接:点我啊╭(╯^╰)╮

题目大意:

    求第 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(knlogVbitset<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");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值