1. 程式人生 > >bzoj 1711: [Usaco2007 Open]Dining吃飯

bzoj 1711: [Usaco2007 Open]Dining吃飯

struct usaco std nbsp return memset fine fff color

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; }

bzoj 1711: [Usaco2007 Open]Dining吃飯