hdu 2444 The Accomodation of Students —— 判斷是否爲二分圖 + 二分圖匹配

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

思路:

題大意就是給出幾個學生,給出兩兩認識的學生,然後判斷是否能分成兩組互相不認識的(判斷是否爲二分圖),如果能,那麼問能最多有幾組兩兩認識的學生(二分圖最大匹配)

判斷二分圖這裏用染色法,遍歷這個圖,對圖用兩個顏色進行染色,要求臨節點顏色不同,如果染色過程中出現臨節點顏色相同情況,那麼就不是二分圖,如果染色成功,那麼是二分圖。

判斷二分圖後,求二分圖最大匹配即可。

 

AC代碼:

#include<cstdio>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>

#define MAXN 205

using namespace std;

int n, m;
bool edge[MAXN][MAXN], vis[MAXN];
int match[MAXN];

bool bfs(int x){
    int color[MAXN] = {0};
    queue<int> que;
    color[x] = 1;
    que.push(x);
    while(!que.empty()){
        int head = que.front();
        for(int i = 1; i <= n; i++){
            if(edge[head][i] == true){
                if(color[i] == 0){
                    color[i] = -color[head];
                    que.push(i);
                }
                else if(color[i] == color[head]){
                    return false;
                }
            }
        }
        que.pop();
    }
    return true;
}

bool dfs(int u){
    for(int i = 1; i <= n; i++){
        if(vis[i] == false && edge[u][i] == true){
            vis[i] = true;
            if(match[i] == 0 || dfs(match[i])){
                match[i] = u;
                return true;
            }
        }
    }
    return false;
}

int main(){
    while(scanf("%d%d", &n, &m) != EOF){
        memset(edge, false, sizeof(edge));
        memset(match, 0, sizeof(match));
        for(int i = 1; i <= m; i++){
            int t1, t2;
            scanf("%d%d", &t1, &t2);
            edge[t1][t2] = true;
        }
        if(!bfs(1)){
            printf("No\n");
        }
        else{
            int sum = 0;
            for(int i = 1; i <= n; i++){
                memset(vis, false, sizeof(vis));
                if(dfs(i)){
                    sum++;
                }
            }
            printf("%d\n", sum);
        }
    }

    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章