POJ1466 Girls and Boys(二分匹配 匈牙利算法)

传送门:http://poj.org/problem?id=1466
题意:给出n个人的连接关系,问你最大的集合,使得集合内没有匹配的人数是多少?

思路:其实就是最大独立集,定理为:最大独立集=n-最大匹配数。因为最大独立数是没匹配到的人+匹配的对数。在本身集合中做二分匹配,求出来的匹配个数是匹配的X部和Y部的总人数,对数=匹配总人数/2。所以这题就是直接做个二分匹配,然后输出n-匹配/2即可。

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<cstdlib>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1e9+7;
typedef pair<int,int> pii;
#define PB push_back
#define MP make_pair
#define X first
#define Y second

int n,link[510];
bool G[510][510],vis[510];
bool dfs(int s){
    for(int i=0;i<n;i++){
        if(G[s][i]&&!vis[i]){
            vis[i]=true;
            if(link[i]==-1||dfs(link[i])){
                link[i]=s;return true;
            }
        }
    }
    return false;
}
int solve(){
    int ans=0;
    memset(link,-1,sizeof link);
    for(int i=0;i<n;i++){
        memset(vis,false,sizeof vis);
        if(dfs(i))ans++;
    }
    return ans;
}
int main(){
 // freopen("D://input.txt","r",stdin);
    while(scanf("%d",&n)!=EOF){
        memset(G,false,sizeof G);
        int t,x;
        for(int i=0;i<n;i++){
            scanf("%d: (%d)",&x,&t);
            while(t--){
                int y;scanf("%d",&y);
                G[x][y]=true;
            }
        }
        int ans=solve();
        printf("%d\n",n-ans/2);
    }
    return 0;
}

你可能感兴趣的:(POJ1466 Girls and Boys(二分匹配 匈牙利算法))