fzu 2141 Sub-Bipartite Graph (贪心)

来源:互联网 发布:2018年java就业前景 编辑:程序博客网 时间:2024/05/17 08:24

题意:给出N个点M条边的图,现在要从中选出两个不相交的点集,使得以这两个点集构成的原图的子图构成一个二分图,并使得边数>=M/2。

思路:一个一个点去染色,对于当前点,判断染哪个颜色使得受益最大就染哪个颜色。往往简单的方法却不容易想啊,想了好久乱七八糟的,在群里问了叉姐才会做Orz

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<set>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100+10;int g[maxn][maxn],color[maxn],B,W;void cal(int p){    int b=0,w=0;    color[p]=1;    for(int i=1;i<p;++i)        if(g[i][p]&&color[i]!=color[p]) b++;    color[p]=2;    for(int i=1;i<p;++i)        if(g[i][p]&&color[i]!=color[p]) w++;    if(b>w) color[p]=1,B++;    else color[p]=2,W++;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int t,n,m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        memset(color,0,sizeof(color));        memset(g,0,sizeof(g));        int u,v;        for(int i=0;i<m;++i)        {            scanf("%d%d",&u,&v);            g[u][v]=g[v][u]=1;        }        B=W=0;        for(int i=1;i<=n;++i)            cal(i);        printf("%d",B);        for(int i=1;i<=n;++i)            if(color[i]==1) printf(" %d",i);        printf("\n");        printf("%d",W);        for(int i=1;i<=n;++i)            if(color[i]==2) printf(" %d",i);        printf("\n");    }    return 0;}

0 0
原创粉丝点击