容量有上下界的可行流
来源:互联网 发布:sqlserver 2008 个人版 编辑:程序博客网 时间:2024/05/17 01:43
【分析】把每行和每列看成一个点,然后先建一个源S和汇T,行就与S连,边的上下界均为要求的和,列就
与T连,上下界也是和,根据限制条件,调整行与列之间的关系。然后图就建好一半了。然后就是
求这个有上下界的网络的可行流
amber的《图论总结》里也写到怎么求
【复杂度】O(Maxflow)
【小结】 这题模型有点难想,但是建图十分麻烦。然后我的程序一直不能AC,我很郁闷,不知道为什么,
先贴一下,如果有人知道的话联系我
type ok=record x,y,nt:longint; end;var tc,n,m,st,en,ptot,tot,sum:longint; e:Array[1..100000]of ok; head,cur,stack,d,inflow,outflow:array[0..500]of longint; map,minm,maxm:array[0..500,0..500]of longint; flag:boolean;procedure add(a,b,c:longint);begin inc(tot); e[tot].x:=a;e[tot].y:=b; e[tot].nt:=head[a];head[a]:=tot; map[a,b]:=c; inc(tot); e[tot].x:=b;e[tot].y:=a; e[tot].nt:=head[b];head[b]:=tot;end;procedure change(x,y,z:longint;ch:char);begin if ch='=' then begin minm[x,y]:=z;maxm[x,y]:=z;end; if ch='>' then begin if z>=minm[x,y] then minm[x,y]:=z+1;end; if ch='<' then begin if z<=maxm[x,y] then maxm[x,y]:=z-1;end; if minm[x,y]>maxm[x,y] then flag:=true;end;procedure fill;var i,j:longint;begin fillchar(outflow,sizeof(outflow),0); fillchar(inflow,sizeof(inflow),0); fillchar(head,sizeof(head),0); fillchar(map,sizeof(map),0); for i:=0 to 500 do for j:=0 to 500 do begin minm[i,j]:=0;maxm[i,j]:=1001; end; st:=0;en:=n+m+1;tot:=0;flag:=false;sum:=0;end;function bfs:boolean;var i,t,k,k1,now:longint;begin for i:=0 to en do d[i]:=-1; stack[1]:=st;d[st]:=0; k:=0;k1:=1; while k<k1 do begin inc(k);now:=stack[k]; t:=head[now];cur[now]:=t; while t<>0 do begin if (map[e[t].x,e[t].y]>0)and(d[e[t].y]=-1) then begin inc(k1);stack[k1]:=e[t].y; d[e[t].y]:=d[now]+1; end; t:=e[t].nt; end; end; if d[en]=-1 then exit(false) else exit(true);end;function dinic(now,tot:longint):longint;var s,temp,flow:longint;begin if now=en then exit(tot); s:=0; while cur[now]<>0 do begin if (map[now,e[cur[now]].y]>0)and(d[e[cur[now]].y]=d[now]+1) then begin temp:=tot;if map[now,e[cur[now]].y]<temp then temp:=map[now,e[cur[now]].y]; flow:=dinic(e[cur[now]].y,temp); inc(s,flow); dec(tot,flow); dec(map[now,e[cur[now]].y],flow); inc(map[e[cur[now]].y,now],flow); if tot=0 then break; end; cur[now]:=e[cur[now]].nt; end; exit(s);end;procedure print;var i,j:longint;begin for i:=1 to n do begin for j:=1 to m do begin write(map[j+n,i]+minm[i,j+n]); if j<m then write(' '); end; writeln; end;end;procedure work;var ans,i,j:longint;begin ans:=0; while bfs do ans:=ans+dinic(st,maxlongint); {writeln(ans); for i:=0 to n+m+3 do begin for j:=0 to m+n+3 do write(map[i,j],' '); writeln; end;writeln;} if ans<>sum div 2 then begin writeln('IMPOSSIBLE');exit;end; st:=0;en:=n+m+1; for i:=ptot+1 to tot do begin map[e[i].x,e[i].y]:=0;//head[e[i].x]:=e[i].nt; end; ans:=0; while bfs do ans:=ans+dinic(st,maxlongint); print;end;procedure main;var lim,tt,i,j,k,x,y,z:longint; ch,tch:char;begin readln(tc); for tt:=1 to tc do begin if tt>1 then writeln; //writeln(tc-tt+1); readln;readln(n,m); //fillchar fill; for i:=1 to n do begin read(x);minm[st,i]:=x;;maxm[st,i]:=x;end;readln; for i:=1 to m do begin read(x);minm[i+n,en]:=x;;maxm[i+n,en]:=x;end;readln; readln(lim); for i:=1 to lim do begin read(x,y,tch,ch,tch,z); if (x=0)and(y=0) then begin for j:=1 to n do for k:=1 to m do change(j,k+n,z,ch); continue; end; if x=0 then for j:=1 to n do change(j,y+n,z,ch); if y=0 then for j:=1 to m do change(x,j+n,z,ch); if (x<>0)and(y<>0) then change(x,y+n,z,ch); end; if flag then begin writeln('IMPOSSIBLE');continue;end; //set up graph for i:=1 to n do begin inc(outflow[st],minm[st,i]);inc(inflow[i],minm[st,i]); add(st,i,maxm[st,i]-minm[st,i]);//add(i,st,0,-1); end; for i:=1 to m do begin inc(outflow[i+n],minm[i+n,en]);inc(inflow[en],minm[i+n,en]); add(i+n,en,maxm[i+n,en]-minm[i+n,en]);//add(en,i+n,0,-1); end; for i:=1 to n do for j:=1 to m do begin inc(outflow[i],minm[i,j+n]);inc(inflow[j+n],minm[i,j+n]); add(i,j+n,maxm[i,j+n]-minm[i,j+n]);//add(j+n,i,0,-1); end; st:=n+m+2;en:=n+m+3;ptot:=tot; for i:=0 to n+m+1 do begin inc(sum,inflow[i]);inc(sum,outflow[i]); add(st,i,inflow[i]);//add(i,st,0,-1); add(i,en,outflow[i]);//add(en,i,0,-1); end; add(n+m+1,0,99999999);//add(0,n+m+1,0,-1); {writeln(sum); for i:=0 to n+m+1 do begin for j:=0 to m+n+1 do write(minm[i,j],' '); writeln; end;writeln; for i:=0 to n+m+1 do begin for j:=0 to m+n+1 do write(maxm[i,j],' '); writeln; end;writeln; for i:=0 to n+m+3 do begin for j:=0 to m+n+3 do write(map[i,j],' '); writeln; end;} work; end;end;begin assign(input,'1.in'); reset(input); assign(output,'1.out'); rewrite(output); main; close(input); close(output);end.
0 0
- 容量有上下界的可行流
- poj 2396(有上下界的可行流)
- poj 2396(有上下界的 可行流)
- hdu4940 有上下界的无源可行流判断
- POJ 2396 Budget 有上下界的可行流
- POJ 2396 Budget 有上下界的可行网络流
- 容量有上下界的最大流 poj 2396 pku
- poj 2396 Budget--有源汇+有上下界+可行流
- 【有上下界最大费用可行流】HDU-4862 Jump
- POJ 2396 有上下界有源汇可行流
- zoj1994 / poj2396 Budget 有上下界可行流求解
- poj2396 Budget(有源汇的有上下界的可行流)
- 从零单练网络流 第三章 有上下界的可行流
- POJ 2396 Budget(无源汇网络有上下界的可行流-Dinic)
- poj 2396 Budget 边容量有上下界的最大流
- 有上下界的流
- POJ 2396 - Budget 有源汇的上下界可行流
- SGU 194 无源汇的上下界可行流
- Java IO一般使用原则
- 带头结点的线性链表的编写与实现
- 第三章作业3.22
- android开发 - SQLite
- hdu1059 Dividing (多重背包)
- 容量有上下界的可行流
- jhead命令详解
- Memcache与Memcached介绍及安装配置
- Java学习笔记之接口Interface
- D. Arthur and Walls(Codeforces Round #297 (Div. 2) 搜索(BFS))
- android开发 - 电话拨号器
- UIBezierPath使用方法
- 设计模式学习(二):工厂模式
- android开发 - 短信发送器