Dining POJ
阿新 • • 發佈:2018-12-20
- 題意:一些牛,每隻牛有 一些 想吃的food and milk,然後問最大能夠滿足多少隻牛。
- 滿足是指的這頭牛即能吃到他喜歡吃的又能喝到他喜歡喝的
- 思路:最大流,關鍵建出圖來,源點匯點肯定是要有的,然後中間呢因為滿足一頭牛的需求是有一個food and milk
- 所以為了保證結果最大隻需要經過每個牛一次就行了,這裡就需要把牛copy一遍中間自己到自己連一條邊權為1的邊
- 而且 為了 達到 "滿足“這個效果 很明顯不能把food and milk 放在一遍 ,需要用牛在中間把他們隔開。
-
整體上一條流量是這樣的 :源點——food——牛——牛——milk——匯點
-
#include<stdio.h> #include<cstring> #include<queue> using namespace std; #define maxn 10005 #define inf 0x3f3f3f3f struct node { int to,v,w; } edge[maxn*20]; int head[maxn],totlen,f; int level[maxn],s,t,n,d; int sum,orz,QYN,cnt=-1; void add(int x,int y,int z) { edge[++cnt].to=head[x]; head[x]=cnt; edge[cnt].v=y; edge[cnt].w=z; edge[++cnt].to=head[y]; head[y]=cnt; edge[cnt].v=x; edge[cnt].w=0; } bool dinic_bfs() { memset(level,0,sizeof(level)); queue<int>que; que.push(0); level[0]=1; while(!que.empty()) { int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].to) { int v=edge[i].v; if(!level[v]&&edge[i].w>0) { level[v]=level[u]+1; que.push(v); } } } return level[sum]!=0; } int dinic_dfs(int u,int cpflow) { if(u==sum)return cpflow; int addflow=0; for(int i=head[u]; i!=-1&&addflow<cpflow; i=edge[i].to) { int v=edge[i].v; if(level[u]+1==level[v]&&edge[i].w>0) { int temp=dinic_dfs(v,min(cpflow-addflow,edge[i].w)); edge[i].w-=temp; edge[i^1].w+=temp; addflow+=temp; } } return addflow; } void dinic() { int maxflow=0; while(dinic_bfs()) maxflow+=dinic_dfs(0,sum); printf("%d\n",maxflow); } int main() { scanf("%d%d%d",&n,&f,&d); sum=n+f+d+n+1; int s1=n+f+n,s2=n+f,s3=f; memset(head,-1,sizeof(head)); for(int i=1; i<=f; i++) add(0,i,1); for(int i=1; i<=n; i++) add(i+s3,i+s2,1); for(int i=1; i<=d; i++) add(s1+i,sum,1); for(int i=1; i<=n; i++) { scanf("%d%d",&f,&d); while(f--) { scanf("%d",&orz); add(orz,s3+i,1); } while(d--) { scanf("%d",&orz); add(s2+i,s1+orz,1); } } dinic(); return 0; }