-
B - Dining
- POJ - 3281
- 题意:一些牛,每只牛有 一些 想吃的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; }
B - Dining POJ - 3281 -网络流拆点模板
猜你喜欢
转载自blog.csdn.net/BePosit/article/details/83863473
今日推荐
周排行