hdu 2444The Accomodation of Students 二分匹配+dfs分组

来源:互联网 发布:淘宝可以说好评返现吗 编辑:程序博客网 时间:2024/05/16 15:42

题目大意:输入有n个人和m对关系,要求把他们分成两组,每组的人中不能有互相认识的,如果不可以分成这样的两组,输出NO,否则输出这两组中最多人的人数。
用染色法,如果有环的话,环里面的点数为奇数的话,就会出现矛盾的情况,就不能分成两组。

#include<stdio.h>#include<cstring>#include<iostream>#include<vector>using namespace std;#define N 211#define clr(a,b) (memset(a,b,sizeof(a)))int link[N],col[N];bool vis[N];vector<int>Map[N];void init(){    clr(link,-1);    clr(vis,false);    clr(col,-1);    for(int i=0;i<N;i++)        Map[i].clear();}int find(int u){    for(int i=0;i<Map[u].size();i++)    {        int v=Map[u][i];        if(!vis[v])        {            vis[v]=true;            if(link[v]==-1||find(link[v]))            {                link[v]=u;                return 1;            }        }    }    return 0;}bool dfs(int u,int tar){    for(int i=0;i<Map[u].size();i++)    {        int v=Map[u][i];        if(col[v]==-1)        {            vis[v]=true;            col[v]=tar^1;            if(!dfs(v,col[v]))                return false;        }        else if(col[v]==(tar^1)) vis[v]=true;        else if(col[v]==tar) return false;    }    return true;}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        init();        for(int i=1;i<=m;i++)        {            int a,b;            scanf("%d%d",&a,&b);            Map[a].push_back(b);        }        int flag=0;        for(int i=1;i<=n;i++)        {            if(vis[i]) continue;            col[i]=1;            if(!dfs(i,col[i]))                {                    flag=1;                    break;                }        }        if(flag)        {            puts("No");            continue;        }        int ans=0;        for(int i=1;i<=n;i++)        {            clr(vis,false);            if(find(i))                ans++;        }        printf("%d\n",ans);    }    return 0;}



0 0
原创粉丝点击