#HDU 2444The Accomodation of Students (二分图的判别方法及最大匹配 原理)


 

Problem 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个对, 每次输入一对表示两人认识,只有认识的人才能住一个房间,问最多可以住多少对?如果不能分成两组,则输出 “NO”

思路 :  首先能看出这是一个二分最大匹配的问题, 但是得先判断该图是不是二分图,二分图只有两个变量还是比较好判断的,用1表示该点为黑色,2表示该点为白色(反过来也无所谓), 只要能够让所有图都着色并且相邻两个点颜色不一样,那么这个图就是一个二分图了。 但是这道题还有一个问题, 他没有告诉你二分图哪些点是第一组,哪些点是第二组,所以我们可以直接把两边都保存了,最后得出来的结果 ➗ 2 就OK了。

AC代码 :

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 2e2 + 5;

int p[maxn][maxn], net[maxn], op[maxn], n, m;
bool vis[maxn];
void init() {
    memset(p, 0, sizeof(p));
    memset(net, 0, sizeof(net));
    memset(op, 0, sizeof(op));
}
bool bfs() {
    queue <int> q;
    q.push(1);
    op[1] = 1;
    while (!q.empty()) {
        int now = q.front();
        q.pop();
        for (int i = 1; i <= n; i++) {
            if (p[now][i]) {
                if (!op[i]) {
                    if (op[now] == 1) op[i] = 2;
                    else op[i] = 1;
                    q.push(i);
                }
                else if (op[now] == op[i]) return 0;
            }
        }
    }
    return 1;
}
bool find_(int x) {
    for (int i = 1; i <= n; i++) {
        if (!vis[i] && p[x][i]) {
            vis[i] = 1;
            if (!net[i] || find_(net[i])) {
                net[i] = x;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    while (cin >> n >> m) {
        init();
        for (int i = 0; i < m; i++) {
            int u, v;
            cin >> u >> v;
            p[u][v] = p[v][u] = 1;
        }
        if (!bfs()) cout << "No" << endl;
        else {
            int ans = 0;
            for (int i = 1; i <= n; i++) {
                memset(vis, 0, sizeof(vis));
                if (find_(i)) ans++;
            }
            cout << (ans >> 1) << endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43851525/article/details/91383928
今日推荐