【codechef】 Special Economic Zone(二分图匹配,难想到)

【codechef】 Special Economic Zone(二分图匹配,难想到)_第1张图片

    Input:
    6 5
    1 2
    2 3
    4 5
    5 6
    6 4
    
    Output:
    1
    

    Explanation

    Ciel will select city 1 and 3 as SEZ. So x = 2 (city 1 and 3), y = 1 (city 2), x - y = 1.

    http://www.codechef.com/MAY15/problems/SEZ/

    方法真的很难想到!想到就容易做了!

    原理其实和这道题目一样:http://blog.csdn.net/cacyth/article/details/48174383

    比较难想到的是,这道题目中的每一条道路都要被抽象理解成上一题的需求,比如a和b直接有一条道路,那么就要理解成:a想要b的书,b想要a的书。然而一个开心城市只能匹配一个不开心城市,一个不开心城市只能匹配一个开心城市,所以必会有一部分开心/不开心城市落单。因为开心和不开心是相对的,所以我们可以理解成那些落单的都是开心城市。题目要求的x-y也就是这个!

#include <bits/stdc++.h>
using namespace std;
#define REP(a, b, c) for(int a = b; a < c; a++)
#define asd(x)              cout<<__LINE__<<" :: "<<#x<< ": "<<x<<endl;
#define asdf(x, y)          cout<<__LINE__<<" :: "<<#x<< ": "<<x<<" | "<<#y<< ": "<<y<<endl;
typedef pair<int,int> ii;
typedef long long LL;
 
const int MAX = 201;
 
int vis[MAX], booked[MAX];
vector<int> G[MAX];
 
bool dfs(int x){
    REP(i, 0, G[x].size()){
        int u = G[x][i];
        if(vis[u]) continue;
        int t = booked[u];
        booked[u] = x;
        vis[u] = true;
        if(t == -1 || dfs(t)) return true;
        booked[u] = t;
    }
    return false;
}
 
 
int main(){
    int n, m;
    cin >> n >> m;
    REP(i, 0, m){
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
 
    int ans = n;
    memset(booked, -1, sizeof booked);
    REP(i, 1, n+1){
        memset(vis, 0, sizeof vis);
        if(dfs(i)){
            ans--;
        }
    }
 
    cout << ans << endl;
    return 0;
} 

你可能感兴趣的:(【codechef】 Special Economic Zone(二分图匹配,难想到))