Kth Minimum Clique

牛客多校第二场 D
题目链接
大概意思就是给出无向图和点权求出第k小团。
我们首先得知道什么叫团:
维基百科解释:在图论领域的一个无向图中,满足两两之间有边连接的顶点的集合,被称为该无向图的团。
知道含义之后。这道题其实也很好做.一个基础的BFS,我们用二进制进行存图和存点,所以我们用bitset,存图是两点i,j可达那么f[i][j] = f[j][i] = 1,bfs时我们还是用二进制存点,走过的点为1没走过为0.
怎么给团进行扩大呢,我们知道&的用法,所以当团中的点与当前的点所存的可达的图&之后 仍然能够得到 原来的团,说明当前点和团中的结点都可达,所以我们可以把它加入团中。
代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef bitset<108> bs;
bs f[1003];
ll w[1005];
struct node{
    ll ans;
    bs x;
    bool operator < (const node &a)const {
        return ans > a.ans;
    }
};
int main()
{
    ll n,m;
    cin >> n >>m;
    for(int i = 1 ; i <= n; i ++){
        cin >> w[i];
    }

    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            char c;
            cin >> c;
            if(c == '1') f[i][j] = 1;//存图
        }
        getchar();
    }
    bs t;
    t.reset();
    priority_queue <node> q;
    q.push({0, t});

    while(!q.empty()){

        node now = q.top();
        q.pop();
        m -- ;
        if(m == 0){
            cout << now.ans << endl;
            return 0;
        }
        
        int flag = 1;
        for(int i = 1; i <= n; i ++){
            if(now.x[i]){
                flag = i + 1;
            }
        }

        for(int i = flag ; i <= n; i ++){
            if(!now.x[i] && (now.x & f[i]) == now.x){//判断是否可以加入团中/如果这个点没有被取过,并且,r为1的地方f[i]也为1,也就是意味着点i与r中的所有的节点都有连通,意味着加入点i后还是一个团,这样才符合题意。
                node next = now;
                next.x[i] = 1;
                next.ans = now.ans + w[i];
                q.push(next);
            }
        }
    }
    cout << -1 << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值