码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3281 Dining

时间:2020-02-16 11:27:34      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:int   scanf   using   cstring   mon   ast   ons   can   queue   

有 n 头牛,f 个食物,d 个饮料。n 头牛,每头牛都有一定的喜好,只喜欢几个食物和饮料。每个食物和饮料只能给一头牛。一头牛只能得到一个食物和饮料。而且一头牛必须同时获得一个食物和一个饮料才能满足,问至多有多少头牛可以获得满足
 
把食物和饮料放在两端,一头牛拆成两个点,两点之间容量为 1,喜欢的食物和饮料跟牛建条边,容量为 1,加个源点和汇点,源点与食物,饮料,汇点的边的容量都是 1,表示每种食物和饮料只有一个
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1014;
const int inf=1e9;
int g[maxn][maxn];
int pre[maxn];
int flow[maxn];
int maxflow;
int N;
queue<int> q;
void init () {
    while (!q.empty()) q.pop();
    fill(pre,pre+maxn,0);
    fill(flow,flow+maxn,0);
    maxflow=0;
    for (int i=0;i<maxn;i++) 
    for (int j=0;j<maxn;j++)
    g[i][j]=0;
}
int bfs (int s,int t) {
    while (!q.empty()) q.pop();
    for (int i=0;i<=N;i++) pre[i]=-1;
    pre[s]=0;
    q.push(s);
    flow[s]=inf;
    while (!q.empty()) {
        int x=q.front();
        q.pop();
        if (x==t) break;
        for (int i=0;i<=N;i++) {
            if (g[x][i]!=0&&pre[i]==-1) {
                pre[i]=x;
                flow[i]=min(flow[x],g[x][i]);
                q.push(i);
            }
        }
    }
    if (pre[t]==-1) return -1;
    else return flow[t];
} 
void Edmonds_Karp (int s,int t) {
    int increase=0;
    while ((increase=bfs(s,t))!=-1) {
        int k=t;
        while (k!=s) {
            int last=pre[k];
            g[last][k]-=increase;
            g[k][last]+=increase;
            k=last;
        }
        maxflow+=increase;
    }
}
int main () {
    int n,f,d;
    while (~scanf("%d %d %d",&n,&f,&d)) {
        init ();
        N=f+d+2*n+1;
        for (int i=1;i<=f;i++) g[0][i]=1;
        for (int i=f+2*n+1;i<=f+2*n+d;i++) g[i][N]=1;
        for (int i=1;i<=n;i++) g[f+2*i-1][f+2*i]=1;
        int k1,k2,u;
        for (int i=1;i<=n;i++) {
            scanf ("%d %d",&k1,&k2);
            while (k1--) {
                scanf ("%d",&u);
                g[u][f+2*i-1]=1;
            }
            while (k2--) {
                scanf ("%d",&u);
                g[f+2*i][f+2*n+u]=1;
            }
        }
        Edmonds_Karp (0,N);
        printf ("%d\n",maxflow);
    }
    return 0;
}

 

POJ3281 Dining

标签:int   scanf   using   cstring   mon   ast   ons   can   queue   

原文地址:https://www.cnblogs.com/zhanglichen/p/12316054.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!