bzoj 1711: [Usaco2007 Open]Dining吃饭

http://www.lydsy.com/JudgeOnline/problem.php?id=1711

 

源点连向食物流量为1,食物连向人流量为1,把人拆点限流,人连向饮料流量为1

饮料连向汇点流量为1,然后,最大流

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
std::queue<int>que;
#define INF 0x7fffffff
const int maxn = 30007;
inline int read() {
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
    return x;
}
int n,f,d,S,T,src,decc;
struct node{
    int v,next,flow;
}edge[maxn];int head[maxn],num=1,cur[maxn],lev[maxn];
void add_edge(int u,int v,int w) {
    edge[++num].v=v;edge[num].next=head[u];head[u]=num;
    edge[num].flow=w;
}
bool bfs() {
    while(!que.empty()) que.pop();
    std::memset(lev,-1,sizeof lev);
    memcpy(cur,head,sizeof head);  
    lev[src]=0;
    que.push(src);int now;
    while(!que.empty()) {
        now=que.front();que.pop();
        for(int i=head[now];i;i=edge[i].next) {
            int v=edge[i].v;
            if(lev[v]==-1&&edge[i].flow>0) {
                lev[v]=lev[now]+1;
                if(v==decc)return true;
                que.push(v);
            }
        }
    }
    return false;
}
int dfs(int now,int flow) {
    if(now==decc)return flow;
    int rest=0,delta;
    for(int &i=cur[now];i;i=edge[i].next) {
        int v=edge[i].v;
        if(lev[v]==lev[now]+1&&edge[i].flow>0) {
            delta=dfs(v,std::min(flow-rest,edge[i].flow));
            if(delta) {
                edge[i].flow-=delta;
                edge[i^1].flow+=delta;
                rest+=delta;if(rest==flow)break;
            }
        }
    }
    if(rest==flow)lev[now]=-1;//满流
    return rest;
}
int Dinic() {
    int ans=0;
    while(bfs()) 
        ans+=dfs(src,INF);
    return ans;
}
inline void add(int a,int b,int flow) {
    add_edge(a,b,flow);add_edge(b,a,0);
}
int main() {
    n=read(),f=read(),d=read();
    src=0;decc=f+n+n+d+1;
    for(int a,b,po,i=1;i<=n;++i) {
        a=read(),b=read();
        for(int j=1;j<=a;++j) po=read(),add(po,f+i,1);
        add(f+i,f+n+i,1);
        for(int j=1;j<=b;++j) po=read(),add(f+n+i,f+n+n+po,1);
    }
    for(int i=1;i<=f;++i)add(src,i,1);
    for(int i=f+n+n+1;i<=f+n+n+d;++i)add(i,decc,INF);
    printf("%d\n",Dinic());
    return 0;
}

 

posted @ 2017-12-23 21:46  zzzzx  阅读(205)  评论(0编辑  收藏  举报