Guardian of Decency UVA - 12083 (二分匹配)

題目鏈接:https://vjudge.net/contest/180830#problem/C

題意:n個學生,老師想帶一部分學生出去但是又怕還有人發展爲情侶,滿足下列條件之一不會成爲情侶:(1)二人身高差大於40cm;(2)二人同性;(3)二人喜歡不同的音樂;(4)二人喜歡相同的運動。求老師最多可以帶多少人出去。

思路:在男女可能發展爲情侶的人之間建邊,求出該二分圖的最大匹配數,用總人數減去最大匹配數即可。

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<sstream>
#include<deque>
#include<stack>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int  maxn = 1000 + 20;
const int  maxt = 300 + 10;
const int mod = 10;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, -1, 1};
const int Dis[] = {-1, 1, -5, 5};
const int inf = 0x3f3f3f3f;
const int MOD = 1000;
int n, m, k;
bool vis[maxn];
int match[maxn];
vector<int> g[maxn];
struct node{
    int height;
    string sex;
    string music;
    string sports;
    void read(){
        cin >> height >> sex >> music >> sports;
    }
}num[maxn];
bool couple(node x, node y){//判斷是否可以成爲情侶
    if(abs(x.height - y.height) > 40) return false;
    if(x.sex == y.sex) return false;
    if(x.music != y.music)return false;
    if(x.sports == y.sports)return false;
    return true;
}

bool dfs(int u){//尋找與u匹配的值
    int v;
    int len = g[u].size();
    for(int i = 0; i < len; ++i){
        v = g[u][i];
        if(vis[v]) continue;
        vis[v] = true;
        if(match[v] == -1 || dfs(match[v])){
            match[v] = u;
            return true;
        }
    }
    return false;
}
int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        for(int i = 1; i < maxn; ++i) g[i].clear();
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i){
            num[i].read();
        }
        for(int i = 1; i <= n; ++i){
            if(num[i].sex == "F") continue;//單向圖,男指向女
            for(int j = 1; j <= n; ++j){
                if(couple(num[i], num[j])){
                    g[i].push_back(j);
                }
            }
        }
        int cnt = 0;//最大匹配數
        memset(match, -1, sizeof match);
        for(int i = 1; i <= n; ++i){
            memset(vis, 0, sizeof vis);
            if(dfs(i)) ++cnt;
        }
//        cout << "CNT == " << cnt << endl;
        printf("%d\n", n - cnt);
    }
    return 0;
}


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