题目大意:求图的第K小团
题目思路:
首先空的团肯定是最小的,然后判断只有一个点的,然后判断只有两个点的,然后判断只有三个点的。。。。。
这和bfs很像,那就这么整,最小的入队,然后一个点的,两个点的,。。。。。得用优先队列,这儿有种十分方便的STL-----bitset
可以相当于一个二进制的数组一样,不过可以直接做数组的与运算,我们记录当前团的点用一个bitset,怎么判断一个点可不可以入队呢,判断是不是这个点和团内的所有点都相连就可以了,也就是用团的bitset和该节点的bitset与。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bitset<105>map1[105];
int a[105];
struct node
{
int id;
ll val;
bitset<105>clique;
bool operator < (const node & a)const
{
return val>a.val;
}
};
priority_queue<node>q;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int x;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%1d",&x);
map1[i][j]=x;
}
}
ll ans=-1;
node st;
st.id=0;st.val=0;
q.push(st);
while(!q.empty())
{
node now=q.top();
q.pop();
k--;
if(!k){
ans=now.val;
break;
}
for(int i=now.id+1;i<=n;i++){
if((now.clique&map1[i])==now.clique){
node next=now;
next.id=i;
next.clique[i]=1;
next.val=now.val+a[i];
q.push(next);
}
}
}
printf("%lld\n",ans);
}