HDU 3605 Escape(多重匹配之多对多的匹配)

来源:互联网 发布:淘宝网电视图片及价格 编辑:程序博客网 时间:2024/06/06 15:51

题意:N个人要要到M个星球上去,告诉每个人可以去哪些星球,以及每个 星球可以住的人数,问所有的人时候都可以安排完
这题和 HDU1669差不多,HDU1669是一对多的匹配,这是多对多的匹配,一对多的匹配是大家的limit都是一样的,多对多的匹配是大家的limit不都一样,每个人有自己的limit,所以开个数组记录每个人的limit

#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<set>#include<map>#include<string>#include<cstring>#include<stack>#include<queue>#include<vector>#include<cstdlib>#define lson (rt<<1),L,M#define rson (rt<<1|1),M+1,R#define M ((L+R)>>1)#define cl(a,b) memset(a,b,sizeof(a));#define LL long long#define P pair<int,int>#define X first#define Y second#define pb push_back#define fread(zcc)  freopen(zcc,"r",stdin)#define fwrite(zcc) freopen(zcc,"w",stdout)using namespace std;const int maxn=100015;const int inf=999999;vector<int> G[maxn];int Nx,limit[15],cnt[15];int matching[15][maxn];bool vis[15];bool dfs(int u){    int N=G[u].size();    for(int i=0;i<N;i++){        int v=G[u][i];        if(vis[v])continue;        vis[v]=true;        if(cnt[v]<limit[v]){            matching[v][cnt[v]++]=u;            return true;        }else {            for(int i=0;i<cnt[v];i++){                if(dfs(matching[v][i])){                    matching[v][i]=u;                    return true;                }            }        }    }    return false;}bool hungar(){    cl(cnt,0);    for(int i=0;i<Nx;i++){        cl(vis,false);        if(!dfs(i))return false;    }    return true;}int main(){    int n,m;    while(~scanf("%d%d",&n,&m)){        for(int i=0;i<n;i++){            for(int j=0;j<m;j++){                int x;                scanf("%d",&x);                if(x)G[i].pb(j);            }        }        for(int i=0;i<m;i++){            scanf("%d",&limit[i]);        }        Nx=n;        if(hungar()){            puts("YES");        }        else {            puts("NO");        }        for(int i=0;i<=n;i++)G[i].clear();    }    return 0;}
0 0
原创粉丝点击