題目連接:https://ac.nowcoder.com/acm/contest/882/Dnode
題意:求給定點權無向圖中,點權和第k小的徹底子圖的點權和。(包括空集)this
思路:從空集開始,每找到一個徹底子圖,經過添加一個點來找到新的徹底子圖(只要該點與原來的全部點鄰接),並存入優先隊列中,每次取出權值和最小的來更新。用bitset來存儲當前徹底子圖中存了哪些點,爲了不更新重複的子圖,須要記錄每一個狀態上一次添加的是哪一個點,下次遍歷該點以後的點,從而防止重複。spa
AC代碼:code
#include<cstdio> #include<algorithm> #include<bitset> #include<queue> using namespace std; typedef long long LL; typedef bitset<105> BS; struct node{ LL sum; int pos; BS vis; node(){} node(LL s,int p,BS v){ this->sum=s; this->pos=p; this->vis=v; } bool operator < (const node& other) const{ return sum>other.sum; } }; int n,k; LL a[105]; BS b[105]; char s[105]; int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=n;++i) scanf("%lld",&a[i]); for(int i=1;i<=n;++i){ scanf("%s",s); for(int j=1;j<=n;++j) b[i][j]=s[j-1]-'0'; } BS tmp; tmp.reset(); priority_queue<node> pq; pq.push(node(0,1,tmp)); while(!pq.empty()){ node now=pq.top();pq.pop(); if(--k==0){ printf("%lld\n",now.sum); return 0; } for(int i=now.pos;i<=n;++i) if((b[i]&now.vis)==now.vis){ now.vis[i]=1; pq.push(node(now.sum+a[i],i+1,now.vis)); now.vis[i]=0; } } printf("-1\n"); return 0; }