hdu4292Food 最大流

来源:互联网 发布:php文件管理插件 简洁 编辑:程序博客网 时间:2024/04/23 21:45
//n个人,每个人选一种食物和一种饮料//有f种食物和d中饮料//每个人对其中的一些食物和饮料喜欢//问怎样分配能使尽量多的人满意//用最大流可以做//一个超级源点连接食物,权值为这种食物的个数//一个超级汇点连接所有饮料,权值为饮料的个数//人为两个点,左边和食物相连,权值为1//右边和饮料相连,权值为1,左人和右人相连,权值为1#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std ;const int maxn = 810 ;const int maxm = 1e5+10;const int inf = 0x7fffffff ;int st = 0 ;int en = maxn-1 ;char str[maxn] ;struct Edge{    int v , w ;    int next ;}edge[maxm<<1] ;int head[maxn] ;int nedge  ;int dis[maxn] ;void addedge(int u , int v , int w){    edge[nedge].v = v ;    edge[nedge].w = w ;    edge[nedge].next = head[u] ;    head[u] = nedge++ ;    edge[nedge].v = u ;    edge[nedge].w = 0 ;    edge[nedge].next = head[v] ;    head[v] = nedge++  ;}bool bfs(){    memset(dis , -1 , sizeof(dis)) ;    dis[st] = 0 ;    queue<int> que ;    que.push(st) ;    while(que.size())    {        int u = que.front() ; que.pop() ;        for(int i = head[u] ; i != -1 ; i = edge[i].next)        {            int v = edge[i].v ;            if(dis[v] == -1 && edge[i].w > 0)            {                dis[v] = dis[u] + 1 ;                que.push(v) ;            }        }    }    if(dis[en] > 0)return true ;    return false ;}int dfs(int u , int mx){    if(u == en)    return mx ;    int ans = 0 ;    int a ;    for(int i = head[u] ; i != -1 ; i = edge[i].next)    {        int v = edge[i].v ;        if(dis[v] == dis[u] + 1 && edge[i].w > 0 && (a = dfs(v , min(mx , edge[i].w))))        {            mx -= a ;            ans += a ;            edge[i].w -= a ;            edge[i^1].w += a ;            if(!mx)break ;        }    }    if(!ans)dis[u] = -1 ;    return ans ;}int main(){    int n , f , d ;    while(~scanf("%d%d%d" , &n , &f ,&d))    {        memset(head , -1 , sizeof(head)) ;        nedge = 0 ;        for(int i = 1;i <= f;i++)        {            int tmp ;            scanf("%d" , &tmp) ;            addedge(st , i , tmp) ;        }        for(int i = 1;i <= d;i++)        {            int tmp  ;            scanf("%d" , &tmp) ;            addedge(i+600 , en , tmp) ;        }        for(int i = 1;i <= n;i++)        {            scanf("%s" , str) ;            for(int j = 0;j < f;j++)            if(str[j] == 'Y')            addedge(j + 1 , i+200 , 1) ;        }        for(int i = 1;i <= n;i++)        {            scanf("%s" , str) ;            for(int j = 0;j < d;j++)            if(str[j] == 'Y')            addedge(i+400 , j + 601 , 1) ;        }        for(int i = 1;i <= n;i++)        addedge(i+200 , i + 400 , 1) ;        int ans = 0 ;        int res ;        while(bfs())            while(res = dfs(st , inf))          ans += res ;        printf("%d\n" , ans) ;    }    return 0 ;}
0 0
原创粉丝点击