Kth Minimum Clique

Kth Minimum Clique

题意: 有一个图,每个节点都有自己的权值,找一个子图,所有节点相加的权值是第k小,(权值为0的图为第一小,也就是空图),且子图的条件是,任意两个点都相邻。

题解:当k==1时,答案是0,当k大于1时,我们先把所有节点加入优先队列中,然后优先队列以权值小的优先,当top出来一个值,再从这个节点能衍生的点加入都优先队列里面。

难点就是,如何判断加入是否与该点相邻,这里要用个很厉害的东西叫bitset,可以百度查下,然后就直接二进制操作了。

#include<bits/stdc++.h>
using namespace std;
const int N = 107;
bitset<N> mp[N];
int n,k,value[N];
 
struct node{
    long long v;
    int pos;
    bitset<N> a;
    node(){}
    node(long long v,int pos,bitset<N> a){
        this->v = v;
        this->pos = pos;
        this->a = a;
    }
    bool operator<(const node &x)const{
        return v > x.v;
    }
};
 
void work(){
    priority_queue<node> q;
    for (int i = 1; i <= n;i++){
        q.push(node(1ll*value[i], i, mp[i]));
    }
    if(k==1){
        printf("0\n");
        return;
    }
    while(!q.empty()){
        node cd = q.top();
        q.pop();
        k--;
        if(k==1){
            printf("%lld\n", cd.v);
            return;
        }
        for (int i = cd.pos + 1; i <= n;i++){
            if(cd.a[i]){
                q.push(node(1ll * (cd.v + 1ll * value[i]), i, mp[i] & cd.a));
            }
        }
    }
    printf("-1\n");
}
 
int main(){
    int x;
    scanf("%d%d", &n,&k);
    for (int i = 1; i <= n;i++){
        scanf("%d" ,& value[i]);
    }
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++){
            scanf("%1d", &x);
            mp[i][j] = x;
        }
    }
    work();
}
发布了10 篇原创文章 · 获赞 1 · 访问量 174

猜你喜欢

转载自blog.csdn.net/weixin_45676038/article/details/104045005