题意:n牛m食品p饮品
第牛有ai种可行食品,bi种可行饮品
现在进行搭配,一头牛如果既有一份可行食品又有一份可行饮品就称为被满足。
求最多满足。
题解:
别忘了牛拆点、
代码:
#include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 405 // 网络图中点 #define G 50000 // 网络图中边 #define inf 0x3f3f3f3f using namespace std; struct KSD { int v,next,len; }e[G]; int head[N],cnt; void add(int u,int v,int len) { cnt++; e[cnt].v=v; e[cnt].len=len; e[cnt].next=head[u]; head[u]=cnt; } queue<int>q; int d[N],s,t; bool bfs() { memset(d,0,sizeof(d)); int i,u,v; while(!q.empty())q.pop(); q.push(s),d[s]=1; while(!q.empty()) { u=q.front(),q.pop(); for(i=head[u];i;i=e[i].next)if(e[i].len) { v=e[i].v; if(!d[v]) { d[v]=d[u]+1; if(v==t) return 1; q.push(v); } } } return 0; } int dinic(int x,int flow) { if(x==t)return flow; int remain=flow,k; int i,v; for(i=head[x];i&&remain;i=e[i].next) { v=e[i].v; if(e[i].len&&d[v]==d[x]+1) { k=dinic(v,min(remain,e[i].len)); if(!k)d[v]=0; e[i^1].len+=k,e[i].len-=k; remain-=k; } } return flow-remain; } int n,m,p,maxflow; bool work() { if(scanf("%d%d%d",&n,&m,&p)==EOF)return 0; int i,a,b,c; s=n+n+m+p+1,t=n+n+m+p+2,cnt=1; memset(head,0,sizeof(head)); maxflow=0; for(i=1;i<=n;i++)add(i,i+n,1),add(i+n,i,0); for(i=1;i<=m;i++)add(s,i+n+n,1),add(i+n+n,s,0); for(i=1;i<=p;i++)add(i+n+n+m,t,1),add(t,i+n+n+m,0); for(i=1;i<=n;i++) { scanf("%d%d",&a,&b); while(a--) { scanf("%d",&c); add(c+n+n,i,1),add(i,c+n+n,0); } while(b--) { scanf("%d",&c); add(i+n,c+n+n+m,1),add(c+n+n+m,i+n,0); } } while(bfs())maxflow+=dinic(s,inf); printf("%d\n",maxflow); return 1; } int main() { // freopen("test.in","r",stdin); while(work()); }
原文地址:http://blog.csdn.net/vmurder/article/details/42488209