FZU 2141 Sub-Bipartite Graph

传送门:FZU 2141 Sub-Bipartite Graph

题目大意

有N个节点有M个边,把这N个点分为两个集合,每个边的顶点都在两个集合之内(因为选出的是子图,所以一条边的两个顶点的都在一个集合也是可以的),但是边的数量要大于等于M/2

 解题思路

这个题目单纯的二分图染色的话,可能会忽略一些不满足的情况。
这个题目就是求分为两个集合,并且保留尽可能多的边。
下面就是怎么保留尽可能多的边呢?
我们枚举两个集合中的元素到顶点i的数量,如果U集合中到i顶点的数量大于V集合中的,那么就把i加入到V集合内;

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int MAXN = 105;
int color[MAXN],cnt,head[MAXN];
int m[MAXN][MAXN];
int main()
{
    int T,N,M;
    int u,v;
    scanf("%d",&T);
    while(T--)
    {
        cnt = 0;
        vector<int> U,V;
        memset(m,0,sizeof m);
        scanf("%d%d",&N,&M);
        for(int i=0;i<M;i++){
            scanf("%d%d",&u,&v);
            m[u][v] = m[v][u] = 1;
        }
        //printf("{%d}\n",N);
        for(int i=1;i<=N;i++){
            int cntu=0,cntv=0;
            for(int j=0;j<U.size();j++)
                if(m[U[j]][i])cntu++;
            for(int j=0;j<V.size();j++)
                if(m[V[j]][i])cntv++;
            if(cntu>cntv)V.push_back(i);
            else U.push_back(i);
            //printf("[%d,%d]\n",U.size(),V.size());
        }
        printf("%d",U.size());
        for(int i=0;i<U.size();i++)printf(" %d",U[i]);
        puts("");
        printf("%d",V.size());
        for(int i=0;i<V.size();i++)printf(" %d",V[i]);
        puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值