zoukankan      html  css  js  c++  java
  • hdu 2444 The Accomodation of Students(最大匹配 + 二分图判断)

    http://acm.hdu.edu.cn/showproblem.php?pid=2444

    The Accomodation of Students
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    
    

    Description

    There are a group of students. Some of them may know each other, while others don't. For example, A and B know each other, B and C know each other. But this may not imply that A and C know each other. 
    Now you are given all pairs of students who know each other. Your task is to divide the students into two groups so that any two students in the same group don't know each other.If this goal can be achieved, then arrange them into double rooms. Remember, only paris appearing in the previous given set can live in the same room, which means only known students can live in the same room. 
    Calculate the maximum number of pairs that can be arranged into these double rooms. 
     

    Input

    For each data set:  The first line gives two integers, n and m(1<n<=200), indicating there are n students and m pairs of students who know each other. The next m lines give such pairs. 
    Proceed to the end of file. 
     

    Output

    If these students cannot be divided into two groups, print "No". Otherwise, print the maximum number of pairs that can be arranged in those rooms. 
     

    Sample Input

    4 4 1 2 1 3 1 4 2 3 6 5 1 2 1 3 1 4 2 5 3 6
     

    Sample Output

    No 3
     
    题目大意: 有n个人,和m种关系,代表a和b认识。要求将n个人放入到两个集合中,每个集合中的人互不认识,A集合中的人找B集合的人住房间,两个人一间,且两个人必须认识,问你最多能住多少间房间。
     
    判断是否为二分图:在无向图G中,如果存在奇数回路,则不是二分图。否则是二分图。
    判断回路奇偶性:把相邻两点染成黑白两色,如果相邻两点出现颜色相同则存在奇数回路。也就是非二分图。
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #define N 210
    
    int G[N][N], vis[N], used[N];
    int m, n, f, c[N];
    
    bool Find(int u)
    {
        int i;
        for(i = 1 ; i <= n ; i++)
        {
            if(!vis[i] && G[u][i])
            {
                vis[i] = 1;
                if(!used[i] || Find(used[i]))
                {
                    used[i] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    void DFS(int x, int color)
    {
        int i;
        for(i = 1 ; i <= n ; i++)
        {
            if(G[x][i])
            {
                if(c[i] == 0)
                {
                    c[i] = -color;//将x相邻的点i染成与其不同的颜色
                    DFS(i, -color);
                }
                else if(c[i] == color)//如果相邻两点颜色相同则不是二分图
                {
                    f = 0;
                    return ;
                }
            }
        }
    }
    
    int main()
    {
        int i, a, b;
        while(~scanf("%d%d", &n, &m))
        {
            memset(G, 0, sizeof(G));
            memset(c, 0, sizeof(c));
            f = 1;
            while(m--)
            {
                scanf("%d%d", &a, &b);
                G[a][b] = G[b][a] = 1;
            }
            c[1] = 1;
            DFS(1, 1);//将1号染成黑色
            if(f == 0)
                printf("No
    ");
            else
            {
                int ans = 0;
                memset(used, 0, sizeof(used));
                for(i = 1 ; i<= n ; i++)
                {
                    memset(vis, 0, sizeof(vis));
                    if(Find(i))
                        ans++;
                }
                printf("%d
    ", ans / 2);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    js Array的方法及属性总结
    js 继承
    js 判断数据类型
    序列化和反序列化
    express 常用方法和插件
    node 常用的对象
    node.js 守护进程
    CentOS7安装Python3.8.1和ansible
    MAC终端终极美化方案
    Linux之top命令详解
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4720224.html
Copyright © 2011-2022 走看看