FZU 2141

来源:互联网 发布:硕士论文修改 淘宝 编辑:程序博客网 时间:2024/06/08 15:02

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

思路:一个一个点去染色,对于当前点,判断染哪个颜色使得受益最大就染哪个颜色,

参考http://blog.csdn.net/qian99/article/details/22994069

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>using namespace std;const int maxn = 100 + 10;#define INF 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define clr(x,y) memset(x,y,sizeof x)int n,m;int maze[maxn][maxn];int col[maxn];int U,V;void calc(int x){    int u = 0,v =0;    for(int i = 1; i <= n; i ++)    if(maze[i][x])    {        if(col[i] != 1)            u ++;        if(col[i] != 2)            v ++;    }    if(u >= v)        col[x] = 1,U ++;    else col[x] = 2,V ++;}int main(){    int Tcase;    scanf("%d",&Tcase);    while(Tcase --)    {        U = 0,V = 0;        clr(maze,0);        clr(col,0);        scanf("%d%d",&n,&m);        for(int i = 1; i  <= m; i ++)        {            int x,y;            scanf("%d%d",&x,&y);            maze[x][y] = 1;        }        for(int i = 1; i <= n; i ++)            calc(i);        cout << U;        for(int i = 1; i <= n; i ++)            if(col[i] == 1)            cout << " " << i ;        cout << endl;        cout << V;        for(int i = 1; i <= n; i ++)            if(col[i] == 2)            cout << " " << i ;        cout << endl;    }    return 0;}


原创粉丝点击