【网络流-最大流-Dinic-建模】POJ3281 Dining:Pascal 解法
来源:互联网 发布:火焰喷射器升级数据 编辑:程序博客网 时间:2024/04/30 23:54
传送门:POJ3281
【题目大意】
有N头奶牛,每一头都有自己喜欢的食物和饮料,且它们只吃自己喜欢的东西。每头牛只能选一个食物与一个饮料现在有F种食物,D种饮料,求最多能够同时满足几头奶牛的需求。
【输入格式】
第一行N,F,D。N代表牛的数量;F代表食物的数量;D代表饮料的数量
接下来2..N+1行:每行前两个数:F[I]与D[I]代表这头牛喜欢食物与饮料的种类数,接下来F+D行代表他喜欢的食物与饮料。
【输出格式】
一个数X:代表最多几头牛能满足。
【大致思路】
Dinic求最大流+邻接表
【建图思路】
最直白的方式是将食物放在左边,分别与源点相连(容量:1);饮料放在右边,分别与汇点相连(容量:1);每头奶牛看作一个点,放在中间。每头奶牛都与其喜爱的食物和饮料连一条边(容量:MAX),然后求这个图的最大流就行了。
但是,题目有限制每头奶牛只能选一份餐,所以要在这个基础上做限制:将表示牛的点一分为二(牛1和牛2),牛1决定所选的食物(与喜爱食物连边),牛2决定所选饮料(与喜爱饮料连边),两者之间再连一条容量为1的边即可。这个做法让每个牛只能选一种套餐。
【代码】
type dinic=record y,r,next,op:longint; end;var g:array[-1..20000] of dinic; level,q,h:array[-1..410] of longint; n,m,i,ans,a,b,c,j,num,vs,vt,f,d,ff,dd,x:longint;function min(a,b:longint):longint;begin if a>b then exit(b) else exit(a);end;function dfs(v,a:longint):longint;var ans,flow,tmp,u,value:longint;begin if (v=vt) or (a=0) then exit(a); ans:=0; tmp:=h[v]; while tmp<>0 do begin u:=g[tmp].y; value:=g[tmp].r; if (level[u]=level[v]+1) then begin flow:=dfs(u,min(a,value)); if flow<>0 then begin g[tmp].r:=g[tmp].r-flow; g[g[tmp].op].r:=g[g[tmp].op].r+flow; ans:=ans+flow; a:=a-flow; if a=0 then break; end; end; tmp:=g[tmp].next; end; exit(ans);end;function bfs:boolean;var i,f,r,tmp,v,u,j:longint;begin fillchar(level,sizeof(level),0); f:=1; r:=1; q[1]:=vs; level[vs]:=1; repeat v:=q[f]; tmp:=h[v]; while tmp<>0 do begin u:=g[tmp].y; if (g[tmp].r<>0) and (level[u]=0) then begin level[u]:=level[v]+1; inc(r); q[r]:=u; if u=vt then exit(true); end; tmp:=g[tmp].next; end; inc(f); until f>r; exit(false);end;procedure add(a,b,c:longint);begin inc(num); g[num].y:=b; g[num].r:=c; g[num].op:=num+1; g[num].next:=h[a]; h[a]:=num; inc(num); g[num].y:=a; g[num].r:=0; g[num].op:=num-1; g[num].next:=h[b]; h[b]:=num;end;procedure init;begin fillchar(h,sizeof(h),0); num:=0; ans:=0; readln(n,f,d); vs:=0; vt:=401; for i:=1 to f do add(vs,i+200,1); for i:=1 to d do add(i+300,vt,1); for i:=1 to n do begin add(i,i+100,1); read(ff,dd); for j:=1 to ff do begin read(x); add(x+200,i,maxlongint); end; for j:=1 to dd do begin read(x); add(i+100,x+300,maxlongint); end; readln; end;end;procedure main;begin init; while bfs do begin ans:=ans+dfs(vs,maxlongint); end; writeln(ans);end;begin main;end.
0 0
- 【网络流-最大流-Dinic-建模】POJ3281 Dining:Pascal 解法
- POJ3281-Dining(最大流Dinic)
- poj3281 dining 经典最大流建模方法
- 【POJ3281 Dining 】最大流
- 【poj3281】【最大流】Dining
- POJ3281 Dining(最大流)
- 【poj3281】Dining 最大流
- POJ3281 Dining 最大流
- 【POJ3281】Dining【最大流】
- poj3281 Dining 最大流
- poj3281 Dining 最大流
- Dining POJ3281 最大流
- poj3281 dining 网络流最大流算法
- POJ3281 网络流 dining
- 【POJ3281】Dining 网络流
- [网络流]poj3281 Dining
- POJ3281 Dining【网络流】
- POJ3281 Dining [最大流应用]
- dtree.js菜单列表加密,实现Code
- 吉普曲线
- SizeClass 和AutoLayout教程2
- 黑马程序员——Java基础语法(一)---关键字、常量、变量、运算符--第2天--第11-26集
- 大数据作业总结
- 【网络流-最大流-Dinic-建模】POJ3281 Dining:Pascal 解法
- Building Remote+Local *nix Develop Environment(II)
- PHP面向对象精华
- 墙内快速下载Android SDK的方法
- GNOME Power Manager not installed correctly. Please contact your system administrator
- easyui-datagrid动态修改url,实现datagrid中数据的更新变化
- const char* const a
- 《大数据时代》第七章读后整理和感悟
- android4.4 Fragment +ViewPager+actionbar 使用