zoukankan      html  css  js  c++  java
  • HDU 2444 The Accomodation of Students(推断是否是二分图)

    题目链接

    题意:n个学生,m对关系,每一对互相认识的能住一个房间。问否把这些学生分成两组,要求每组的学生都互不认识。求最多须要多少个房间。


    能否分成两组?也就是说推断是不是二分图,推断二分图的办法,用染色法

    把初始点染成黑色,然后与之相连的染成白色,反复,使路径黑白相间,

    假设当前点的颜色和与他相连点的颜色同样时,则说明这个图不是二分图


    求最多须要多少个房间?也就是求最大匹配数。


    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <math.h>
    #define init(a) memset(a,0,sizeof(a))
    #define PI acos(-1,0)
    using namespace std;
    const int maxn = 310;
    const int maxm = 100001;
    #define lson left, m, id<<1
    #define rson m+1, right, id<<1|1
    #define min(a,b) (a>b)?b:a
    #define max(a,b) (a>b)?a:b
    const int N = 50010;
    int ma[maxn][maxn];
    int line[maxn],color[maxn];
    bool vis[maxn];
    int k,n,m;
    bool flag;
    int DFS(int u)
    {
        for(int  v = 1;v<=n;v++)
        {
            if(ma[u][v]==1 && !vis[v])
            {
                vis[v] = 1;
                if(line[v]==-1 || DFS(line[v]))
                {
                    line[v] = u;
                    return 1;
                }
            }
        }
        return 0;
    }
    void dfs(int u,int st)
    {
        if(flag == false)
            return ;
        for(int v = 1;v <= n;v++)
        {
            if(ma[u][v])
        {
            if(!color[v])
            {
                color[v]= -st;//黑染白 / 白染黑
                dfs(v,color[v]);
            }
            else if(color[v]==st)
            {
                flag = false;
                return;
            }
    
        }
        }
    
    }
    bool judge()
    {
        flag = true;
        color[1] = 1 ;//1代表黑色,-1代表白色
        dfs(1,1) ;
        return flag;
    }
    int K_M()
    {
        int ans = 0;
        memset(line,-1,sizeof(line));
        for(int i  = 1;i<=n;i++)
        {
            init(vis);
            ans += DFS(i);
        }
        return ans;
    }
    int main()
    {
        int a,b;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init(ma);
            memset(color,0,sizeof(color));
            for(int i = 1;i<=m;i++)
            {
                scanf("%d%d",&a,&b);
                ma[a][b]  = 1;
            }
            if(!judge())
            {
                puts("No");
                continue;
            }
            int ans = K_M();
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    我来悟微服务(1)-夜观天象
    静夜思-十年总结与展望
    【Orleans开胃菜系列2】连接Connect源码简易分析
    【Orleans开胃菜系列1】不要被表象迷惑
    .Net单元测试业务实践
    未能使用“Csc”任务的输入参数初始化该任务
    面试发散思维
    Linux部署DotNetCore记录
    一步一步来熟悉Akka.Net(一)
    午夜杂谈
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4230893.html
Copyright © 2011-2022 走看看