hdu3605——Escape(二分图多重匹配)

来源:互联网 发布:交通组织优化定义 编辑:程序博客网 时间:2024/06/05 19:03

Problem Description
2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets.

Input
More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most..
0 <= ai <= 100000

Output
Determine whether all people can live up to these stars
If you can output YES, otherwise output NO.

Sample Input
1 1
1
1

2 2
1 0
1 0
1 1

Sample Output
YES
NO

n个人移民到m个星球上,每个星球限制了人数,用一个0-1矩阵表示第i行的人是否愿意移民到第j列个星球上。最后输出所有人是否能顺利移民。
这道题有两种做法,一种是网络流加缩点,因为n很大m很小,一定有许多人的想去同一个星球,但二进制缩点什么的看不懂,只好放弃。
第二种是二分图多重匹配,大概是用num数组记录这个点已经住了多少人,如果不超过容量cap就还能在加,或者去别的星球,如果还是不行就失败了。

#include <iostream>#include <cstring>#include <string>#include <vector>#include <queue>#include <cstdio>#include <set>#include <cmath>//#include <map>#include <algorithm>#define INF 0x3f3f3f3f#define MAXN 110000#define Mod 10001using namespace std;int map[MAXN][12];int vis[12],link[12][MAXN];int num[12],cap[12];int n,m;int find(int v){    for(int i=1;i<=m;++i)    {        if(map[v][i]&&!vis[i])        {                vis[i]=1;                if(num[i]<cap[i])                {                    link[i][++num[i]]=v;                    return 1;                }                for(int j=1;j<=num[i];++j)                {                    if(find(link[i][j]))                    {                        link[i][j]=v;                        return 1;                    }                }        }    }    return 0;}int main(){    while(~scanf("%d%d",&n,&m))    {        for(int i=1;i<=n;++i)            for(int j=1;j<=m;++j)                scanf("%d",&map[i][j]);        for(int i=1;i<=m;++i)            scanf("%d",&cap[i]);        memset(num,0,sizeof(num));        int flag=0;        for(int i=1;i<=n;++i)        {            memset(vis,0,sizeof(vis));            if(!find(i))            {                flag=1;                break;            }        }        if(flag)            puts("NO");        else            puts("YES");    }    return 0;}
0 0
原创粉丝点击