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

D.Kth Minimum Clique(bitset优化)

题面

题意:

求一个无向连通图的第$K$大完全子图。

思路:

新技能:利用$bitset$存储子图,假设把$i$能到达的点的位设置为$1$,这样我们就可以通过直接进行与运算来判断这个点是否能放到现在的团里面。然后BFS即可。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<bits/stdc++.h>

using namespace std;
bitset<105> bs[105];
long long w[105];
char maze[105][105];
struct node{
bitset<105> cl;
long long w;
int last;
};
bool operator<(node a,node b){
return a.w>b.w;
}
priority_queue<node> q;
int n,k;
long long bfs(){
node now;
now.cl.reset();
now.w=0;
now.last=0;

q.push(now);
while(!q.empty()){
node rt=q.top();q.pop();
if(--k==0) return rt.w;

for(int i=rt.last+1;i<=n;i++){
if(((bs[i]&rt.cl).count()==rt.cl.count())){
node pt=rt;
pt.cl[i]=1;
pt.last=i;
pt.w+=w[i];
q.push(pt);
}
}
}
return -1;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>maze[i][j];
if(maze[i][j]=='1'){
bs[i][j]=1;
}
}
}
cout<<bfs()<<endl;
return 0;
}