您的位置:首页 > 理论基础 > 计算机网络

道路修建 (网络流)

2015-06-12 17:46 369 查看
const INF=2000000000;
const maxn=4008;
var r:array[0..maxn] of longint;
eg:array[0..1000008] of record u,v,w,nt:longint; end;
el:longint;
lt:array[0..maxn] of longint;
h:array[0..maxn] of longint;
b:array[0..10008] of longint;
i,j,k,n,s,t,m,x,y:longint;
function op(i,j:longint):longint; inline;
begin
exit((i-1)*n+j);
end;
function calc(x,y:longint):longint; inline;
begin
exit(trunc(10*ln(233*(x-y)*(x-y)+1)));
end;
procedure adt(u,v,w:longint);
begin
inc(el);
eg[el].u:=u;
eg[el].v:=v;
eg[el].w:=w;
eg[el].nt:=lt[u];
lt[u]:=el;
end;
procedure add(u,v,w:longint);
begin
//   writeln(u,' ',v,' ',w);
adt(u,v,w); adt(v,u,0);
end;
procedure bfs;
var i,l,r,x:longint;
begin
fillchar(h,sizeof(h),$7f);
h[t]:=0;
l:=1; r:=1; b[1]:=t;
while l<=r do
begin
x:=b[l];
i:=lt[x];
while i<>0 do
begin
if (h[eg[i].v]>=n) and (eg[i xor 1].w>0) then
begin
inc(r);
b[r]:=eg[i].v;
h[eg[i].v]:=h[x]+1;
end;
i:=eg[i].nt;
end;
inc(l);
end;
end;
function min(a,b:longint):longint; inline;
begin
if a<b then exit(a) else exit(b);
end;
function dfs(u,inl:longint):longint;
var i,v,outl:longint;
begin
if u=t then exit(inl);
dfs:=0;
i:=lt[u];
while i<>0 do
begin
v:=eg[i].v;
if (eg[i].w>0) and (h[u]=h[v]+1) then
begin
outl:=dfs(v,min(eg[i].w,inl));
dec(inl,outl);
inc(dfs,outl);
dec(eg[i].w,outl);
inc(eg[i xor 1].w,outl);
if inl=0 then break;
end;
i:=eg[i].nt;
end;
if inl=0 then h[u]:=-1;
end;
function dinic:longint;
var sum:longint;
begin
bfs;
sum:=0;
while h[s]<n do
begin
sum:=sum+dfs(s,INF);
bfs;
//writeln(sum);
end;
exit(sum);
end;
begin
//assign(input,'1.in');reset(input);
el:=1;
readln(n,m);
for i:=1 to n do read(r[i]);
s:=0; t:=n*n+1;
for i:=1 to n do
begin
if i=1 then add(s,op(i,1),calc(0,r[i]))
else add(s,op(i,1),INF);
for j:=2 to n do
if i<>1 then
add(op(i,j-1),op(i,j),calc(j-1,r[i]))
else
add(op(i,j-1),op(i,j),INF);
if i=1 then add(op(i,n),t,INF) else add(op(i,n),t,calc(n,r[i]))
end;

for i:=1 to m do
begin
readln(x,y);
for k:=2 to n do
begin
add(op(x,k),op(y,k-1),INF);
add(op(y,k),op(x,k-1),INF);
end;
end;
n:=n*n+1;
writeln(dinic);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: