您的位置:首页 > 其它

太空飞行计划

2012-04-11 18:17 120 查看
网络流与线性规划24题第二题。

题解中算法很明显,但是有一个地方不完美,就是方案,数据中存在这样的情况,对于一个最优方案,再加上一个实验,总收益不变,数据就把这个实验也算在内了。

所以输出时不是和s相连的点,而是与t不连通的点。

View Code

program fly(input,output);
const
oo = 19950714;
var
dist    : array[0..500] of longint;
f    : array[0..500,0..500] of longint;
q    : array[0..2000] of longint;
v    : array[0..400] of boolean;
n,m    : longint;
w    : array[0..200] of longint;
cost    : array[0..200] of longint;
s,t    : longint;
flow    : longint;
procedure init;
var
x,i : longint;
begin
readln(m,n);
s:=0;
t:=m+n+2;
for i:=1 to m do
begin
read(w[i]);
f[s,i]:=w[i];
f[i,s]:=0;
while not eoln do
begin
read(x);
f[i,m+x]:=oo;
f[m+x,i]:=0;
end;
readln;
end;
for i:=1 to n do
begin
read(cost[i]);
f[m+i,t]:=cost[i];
f[t,m+i]:=0;
end;
for i:=s to t do
f[i,i]:=0;
end; { init }
procedure swap(var aa,bb :longint );
var
tt : longint;
begin
tt:=aa;
aa:=bb;
bb:=tt;
end; { swap }
function bfs(now: longint ):boolean;
var
head,tail : longint;
i         : longint;
begin
head:=0;
tail:=1;
for i:=s to t do
dist[i]:=-1;
dist[now]:=0;
q[1]:=now;
while head<tail do
begin
inc(head);
for i:=s to t do
if f[q[head],i]>0 then
if dist[i]=-1 then
begin
dist[i]:=dist[q[head]]+1;
inc(tail);
q[tail]:=i;
end;
end;
if dist[t]=-1 then
exit(false);
exit(true);
end; { bfs }
function min(aa,bb :longint ):longint;
begin
if aa<bb then
exit(aa);
exit(bb);
end; { min }
function dfs(now,minflow: longint ):longint;
var
i   : longint;
tmp : longint;
begin
if now=t then
exit(minflow);
for i:=s to t do
if f[now,i]>0 then
if dist[i]=dist[now]+1 then
begin
tmp:=dfs(i,min(minflow,f[now,i]));
if tmp<>0 then
begin
inc(f[i,now],tmp);
dec(f[now,i],tmp);
exit(tmp);
end;
end;
exit(0);
end; { dfs }
procedure main;
var
tmp,i,j : longint;
sum       : longint;
begin
flow:=0;
while bfs(s) do
begin
tmp:=dfs(s,oo);
while tmp<>0 do
begin
inc(flow,tmp);
tmp:=dfs(s,oo);
end;
end;
for i:=s to t-1 do
for j:=i+1 to t do
swap(f[i,j],f[j,i]);
bfs(t);
fillchar(v,sizeof(v),true);
for i:=1 to m do
if dist[i]<>-1 then
v[i]:=false;
for i:=1 to m do
if v[i] then
write(i,' ');
writeln;
fillchar(v,sizeof(v),true);
for i:=1 to n do
if dist[i+m]<>-1 then
v[i]:=false;
for i:=1 to n do
if v[i] then
write(i,' ');
writeln;
sum:=0;
for i:=1 to m do
inc(sum,w[i]);
writeln(sum-flow);
end; { main }
begin
assign(input,'fly.in');reset(input);
assign(output,'fly.out');rewrite(output);
init;
main;
close(input);
close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: