HDU 2444 二分图的判定+最大匹配

xg

题意

  n个人,m个关系。对于第i个关系,x互相认识y。

  问能否把n个人分成两组,使得一组里的人互相不认识。

  如果能,则要开ans个房间,每个房间两人,使得每个房间里的人互相认识。

思路

  第一个问题就是01染色判断能否染色成功。

  第二个问题裸最大匹配

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector> 

#define bug cout<<"--------------"<<endl
#define sp ' '
using namespace std;
typedef long long ll;

const int maxn = 8e4+10;
int n,m,cnt;
int tot = 0;
int head[maxn],ver[maxn],edge[maxn],nextt[maxn];
void add(int x,int y)
{
    ver[++tot] = y,nextt[tot] = head[x] , head[x] = tot;
}
int col[maxn],cun[maxn];
int flag = 0,tail = 0;
int vis[maxn];
int tc = 0;
int hc[maxn],vc[maxn],nc[maxn];
void add_c(int x,int y)
{
    //cout<<x<<sp<<y<<endl;
    vc[++tc] = y,nc[tc] = hc[x] , hc[x] = tc;
}
int dfs01(int s)
{
    int v;
    queue<int>que;
    col[s]=0;
    que.push(s);
    while(que.size())
    {
        int x =que.front();
        que.pop();
        if(col[x] == 0) cun[++tail] = x;
        for(int i=head[x]; i; i=nextt[i])
        {
            int y = ver[i];
            if(col[y]==-1)
            {
                col[y]=col[x]^1;
                que.push(y);
            }
            else if(col[y]==col[x])
            {
                return 0;
            }
        }
    }
    return 1;
}
int match[maxn];

bool dfs(int x)
{
    for(int i = head[x],y;i; i = nextt[i]){    
        if(!vis[y = ver[i]]){
            vis[y] = 1;
            if(!match[y] || dfs(match[y])){
                match[y] = x; return 1;
            }
        }
    }
    return 0;
}
void clearr()
{
    memset(head,0,sizeof(head));
    tot = 0;
    memset(col,-1,sizeof(col));
    flag = 0;
    memset(vis,0,sizeof(vis));
    memset(hc,0,sizeof(hc));
    tc = 0;
    memset(match,0,sizeof(match));
    tail = 0;
}
int main()
{
    //freopen("input.txt", "r", stdin);
    while(scanf("%d%d",&n,&m) != EOF){
        clearr();
        for(int i =1 ;i <=m;++i){
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        flag = 0;
        for(int i = 1;i <=n;++i){
            if(col[i] == -1){
                if(dfs01(i) == 0){
                    flag = 1;
                    break;
                }
            }
        }
        if(flag == 1){
            printf("No\n");
            continue;
        }

        int ans = 0;

        for(int i = 1;i <= n;++i){
            memset(vis,0,sizeof(vis));
            if(dfs(i)) ans++;
        } 
        printf("%d\n",ans/2 );
    }

}

 

posted @ 2020-08-24 10:22  阿斯水生产线  阅读(70)  评论(0编辑  收藏  举报