上下界网络流 poj2396

经典的方格取数。

汇总一下几个重要网址

找题解 http://hi.baidu.com/zfy0701/blog/item/6449d82a64e15e3e5343c1ba.html

找图 http://acmicpc.org.cn/wiki/index.php?title=2003_Tehran_Preliminary_Budget_Solution(无向边其实是有向边)

找数据 http://www.ida.liu.se/projects/progcontest/progsm/2003/ (我没找到ans,但可以拍)

下面是我自己的心得...

使n*m的矩阵每行每列元素和等于某个值且每个元素满足约束条件,若有则输出矩阵,若无则输出'IMPOSSIBLE'。

input:

数据组数

(空行)

行列数

每行元素和

每列元素和

约束条件数

约束条件

(空行)

(下组数据)

对于约束条件(x,y,z,k)

若x<>0 and y<>0 then 第x行第y列元素满足 z(>,=,<) k

若x=0 then 每行第y列元素满足 z(>,=,<) k

y=0 亦然

若(x=0)and(y=0) then 整个矩阵满足 z(>,=,<) k

 

回家再编辑

先贴代码

const max=1073741819;maxnm=500; var b:array[0..maxnm,0..maxnm]of longint; flow,flow1,down,up:array[0..maxnm,1..maxnm]of longint; ru,chu,d,st:array[0..maxnm]of longint; i,n,m,ans,tot,s,t,tt,ss:longint; procedure origin; begin fillchar(down,sizeof(down),0);fillchar(up,sizeof(up),127); fillchar(flow,sizeof(flow),0);fillchar(ru,sizeof(ru),0); fillchar(chu,sizeof(chu),0);fillchar(b,sizeof(b),0) end; procedure getout; var i,j:longint; begin for i:=1 to n do begin for j:=1+n to m+n do write(flow1[i,j]-flow[i,j]+down[i,j],' '); writeln end end; function bfs(ss:longint):boolean; var h,r,i,ne:longint; begin fillchar(st,sizeof(st),0);fillchar(d,sizeof(d),127); h:=0;r:=1;st[r]:=ss;d[ss]:=0; repeat inc(h);ne:=st[h]; for i:=1 to b[ne,0] do if (flow[ne,b[ne,i]]>0)and(d[ne]+1<d[b[ne,i]]) then begin d[b[ne,i]]:=d[ne]+1;inc(r);st[r]:=b[ne,i] end until h>=r; if d[tt]>max then exit(false); exit(true) end; function dfs(x,low:longint):longint; var i,ne,tmp:longint; begin if x=tt then exit(low);dfs:=0; for i:=1 to b[x,0] do if (d[b[x,i]]=d[x]+1)and(flow[x,b[x,i]]>0) then begin ne:=b[x,i]; if flow[x,ne]<low then tmp:=dfs(ne,flow[x,ne]) else tmp:=dfs(ne,low); if tmp=0 then d[ne]:=max; dec(low,tmp);dec(flow[x,ne],tmp);inc(flow[ne,x],tmp);inc(dfs,tmp); if low=0 then break end; end; procedure dinic; begin while bfs(ss) do inc(tot,dfs(ss,maxlongint)); if tot<ans then writeln('IMPOSSIBLE') else getout end; procedure init; var i,j,w,x,y,k,c:longint; z1,z:char; begin readln(n,m);ss:=0;s:=n+m+1;t:=s+1;tt:=t+1;ans:=0;tot:=0; origin; for i:=1 to n do begin read(x);down[s,i]:=x;up[s,i]:=x;{inc(b[s,0]);b[s,b[s,0]]:=i;inc(b[i,0]);b[i,b[i,0]]:=s;}chu[s]:=chu[s]+x;ru[i]:=ru[i]+x end; for i:=1+n to m+n do begin read(x);down[i,t]:=x;up[i,t]:=x;{inc(b[i,0]);b[i,b[i,0]]:=t;inc(b[t,0]);b[t,b[t,0]]:=i;}chu[i]:=chu[i]+x;ru[t]:=ru[t]+x end; readln(c); for i:=1 to c do begin readln(x,y,z1,z,k);if y<>0 then y:=y+n; if (x=0)and(y<>0) then for j:=1 to n do case z of '>':if k+1>down[j,y] then down[j,y]:=k+1; '=':begin down[j,y]:=k;up[j,y]:=k end; '<':if k-1<up[j,y] then up[j,y]:=k-1 end else if (x<>0)and(y=0) then for j:=1+n to m+n do case z of '>':if k+1>down[x,j] then down[x,j]:=k+1; '=':begin down[x,j]:=k;up[x,j]:=k end; '<':if k-1<up[x,j] then up[x,j]:=k-1 end else if (x=0)and(y=0) then for j:=1 to m+n do for w:=1 to m+n do begin if j<>w then case z of '>':if k+1>down[j,w] then down[j,w]:=k+1; '=':begin down[j,w]:=k;up[j,w]:=k end; '<':if k-1<up[j,w] then up[j,w]:=k-1 end end else case z of '>':if k+1>down[x,y] then down[x,y]:=k+1; '=':begin down[x,y]:=k;up[x,y]:=k end; '<':if k-1<up[x,y] then up[x,y]:=k-1 end end; for i:=1 to n do for j:=1+n to m+n do if i<>j then begin flow[i,j]:=up[i,j]-down[i,j];inc(chu[i],down[i,j]);inc(ru[j],down[i,j]); inc(b[i,0]);b[i,b[i,0]]:=j;inc(b[j,0]);b[j,b[j,0]]:=i end; flow[t,s]:=maxlongint;flow[s,t]:=0; inc(b[s,0]);b[s,b[s,0]]:=t;inc(b[t,0]);b[t,b[t,0]]:=s; for i:=1 to t do if ru[i]>chu[i] then begin flow[ss,i]:=ru[i]-chu[i];inc(b[ss,0]);b[ss,b[ss,0]]:=i;inc(b[i,0]);b[i,b[i,0]]:=ss;ans:=ans+flow[ss,i] end else begin flow[i,tt]:=chu[i]-ru[i];inc(b[tt,0]);b[tt,b[tt,0]]:=i;inc(b[i,0]);b[i,b[i,0]]:=tt end; flow1:=flow; dinic; readln;writeln end; begin readln(i); while i>0 do begin init;dec(i) end end.  

你可能感兴趣的:(上下界网络流 poj2396)