十三、网络流
2015-07-14 22:18
531 查看
网络流的最经典应用就是最大流....给定一个图...给出每条边能流过的最大流量...求源点到汇点的最大流量....
求解网络流的基本思想就是每次寻找增广路(就是源点到汇点的一条可行路)..然后ans+=增广路能流过的流量..更新剩余网络..然后再做增广路...直到做不出增广路..关于网络流入门最难理解的地方就是剩余网络了....为什么在找到一条增广路后...不仅要将每条边的可行流量减去增广路能流过的流量...还要将每条边的反向弧加上增广路能流过的流量.?..原因是在做增广路时可能会阻塞后面的增广路...或者说做增广路本来是有个顺序才能找完最大流的.....但我们是任意找的...为了修正...就每次将流量加在了反向弧上...让后面的流能够进行自我调整...剩余网络的更新(就在原图上更新就可以了)。
注意:
当要控制流量时可拆点,当有多个源点或汇点时可建立超级源点或超级汇点。
可观察数据范围推测是否用网络流。
网络流模板最好背下来。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
模板:
type
node=record
y,r,next,op:longint;
end;
var
g:array [1..400] of node;
h,level,q:array [1..400] of longint;
i,j,m,n,ans,a,b,c,vs,vt,tot:longint;
function min(x,y:longint):longint;
begin
if x<y then
exit(x);
exit(y);
end;
function dfs(v,a:longint):longint;
var
tmp,u,ans,value,flow:longint;
begin
if (v=vt) or (a=0) then exit(a);
ans:=0;
tmp:=h[v];
while tmp<>-1 do
begin
u:=g[tmp].y;
value:=g[tmp].r;
if level[v]+1=level[u] 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
u,tmp,l,f,v:longint;
begin
fillchar(level,sizeof(level),0);
q[1]:=vs;
level[vs]:=1;
l:=1;
f:=1;
repeat
v:=q[l];
tmp:=h[v];
while tmp<>-1 do
begin
u:=g[tmp].y;
if (g[tmp].r<>0) and (level[u]=0) then
begin
level[u]:=level[v]+1;
inc(f);
q[f]:=u;
if u=vt then exit(true);
end;
tmp:=g[tmp].next;
end;
inc(l);
until l>f;
exit(false);
end;
procedure add(a,b,c:longint);
begin
inc(tot);
g[tot].y:=b;
g[tot].r:=c;
g[tot].next:=h[a];
h[a]:=tot;
g[tot].op:=tot+1;
inc(tot);
g[tot].y:=a;
g[tot].r:=0;
g[tot].next:=h[b];
h[b]:=tot;
g[tot].op:=tot-1;
end;
begin
while not eof do
begin
fillchar(g,sizeof(g),0);
fillchar(h,sizeof(h),$ff);
fillchar(level,sizeof(level),0);
fillchar(q,sizeof(q),0);
readln(n,m);
tot:=0;
ans:=0;
vs:=1;
vt:=m;
for i:=1 to n do
begin
readln(a,b,c);
add(a,b,c);
end;
while bfs do
ans:=ans+dfs(vs,maxlongint);
writeln(ans);
end;
end.
有几道网络流题目:
poj1273
poj1274
poj1149
poj3281
poj3498
求解网络流的基本思想就是每次寻找增广路(就是源点到汇点的一条可行路)..然后ans+=增广路能流过的流量..更新剩余网络..然后再做增广路...直到做不出增广路..关于网络流入门最难理解的地方就是剩余网络了....为什么在找到一条增广路后...不仅要将每条边的可行流量减去增广路能流过的流量...还要将每条边的反向弧加上增广路能流过的流量.?..原因是在做增广路时可能会阻塞后面的增广路...或者说做增广路本来是有个顺序才能找完最大流的.....但我们是任意找的...为了修正...就每次将流量加在了反向弧上...让后面的流能够进行自我调整...剩余网络的更新(就在原图上更新就可以了)。
注意:
当要控制流量时可拆点,当有多个源点或汇点时可建立超级源点或超级汇点。
可观察数据范围推测是否用网络流。
网络流模板最好背下来。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
模板:
type
node=record
y,r,next,op:longint;
end;
var
g:array [1..400] of node;
h,level,q:array [1..400] of longint;
i,j,m,n,ans,a,b,c,vs,vt,tot:longint;
function min(x,y:longint):longint;
begin
if x<y then
exit(x);
exit(y);
end;
function dfs(v,a:longint):longint;
var
tmp,u,ans,value,flow:longint;
begin
if (v=vt) or (a=0) then exit(a);
ans:=0;
tmp:=h[v];
while tmp<>-1 do
begin
u:=g[tmp].y;
value:=g[tmp].r;
if level[v]+1=level[u] 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
u,tmp,l,f,v:longint;
begin
fillchar(level,sizeof(level),0);
q[1]:=vs;
level[vs]:=1;
l:=1;
f:=1;
repeat
v:=q[l];
tmp:=h[v];
while tmp<>-1 do
begin
u:=g[tmp].y;
if (g[tmp].r<>0) and (level[u]=0) then
begin
level[u]:=level[v]+1;
inc(f);
q[f]:=u;
if u=vt then exit(true);
end;
tmp:=g[tmp].next;
end;
inc(l);
until l>f;
exit(false);
end;
procedure add(a,b,c:longint);
begin
inc(tot);
g[tot].y:=b;
g[tot].r:=c;
g[tot].next:=h[a];
h[a]:=tot;
g[tot].op:=tot+1;
inc(tot);
g[tot].y:=a;
g[tot].r:=0;
g[tot].next:=h[b];
h[b]:=tot;
g[tot].op:=tot-1;
end;
begin
while not eof do
begin
fillchar(g,sizeof(g),0);
fillchar(h,sizeof(h),$ff);
fillchar(level,sizeof(level),0);
fillchar(q,sizeof(q),0);
readln(n,m);
tot:=0;
ans:=0;
vs:=1;
vt:=m;
for i:=1 to n do
begin
readln(a,b,c);
add(a,b,c);
end;
while bfs do
ans:=ans+dfs(vs,maxlongint);
writeln(ans);
end;
end.
有几道网络流题目:
poj1273
poj1274
poj1149
poj3281
poj3498
相关文章推荐
- loadrunner性能测试(http+json)
- android开发步步为营之67:使用android开源项目android-async-http异步下载文件
- 网络设备的文件管理
- 罗无线网络电话
- 网络笑话
- iOS开发--http请求设置Cookie
- 已知ip地址和其子网掩码如何求网络号子网号主机号
- iOS网络协议----HTTP/TCP/IP浅析
- Erlang--TCP学习(四)并行web server篇
- 云计算和大数据时代网络技术揭秘(三)安全的网络准入
- HTTP POST GET 本质区别详解
- 云计算和大数据时代网络技术揭秘(二)云与网的关系
- Erlang--TCP学习(三)串行web server篇
- SSL构建单双向https认证!https部署及注意事项!
- 网络流 增广路 入门好文章(转)
- HTTP常见状态码
- tableView的网络数据获取
- HTTP
- 常识说明--HTTPS真的很慢吗?NO!
- Windows 7 IIS (HTTP Error 500.21 - Internal Server Error)解决