晨跑
问题描述:
Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑、仰卧起坐等等,不过到目前为止,他坚持下来的只有晨跑。
现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交。Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N。
Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路口。Elaxia耐力不太好,他希望在一个周期内跑的路程尽量短,但是又希望训练周期包含的天数尽量长。
除了练空手道,Elaxia其他时间都花在了学习和找MM上面,所有他想请你帮忙为他设计一套满足他要求的晨跑计划。
输入格式:
第一行:两个数N,M。表示十字路口数和街道数。
接下来M行,每行3个数a,b,c,表示路口a和路口b之间有条长度为c的街道(单向)。
输出格式:
两个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长度。
样例输入:
7 10
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
2 5 5
3 6 6
5 7 1
6 7 1
样例输出:
2 11
数据范围:
对于30%的数据,N ≤ 20,M ≤ 120。
对于100%的数据,N ≤ 200,M ≤ 20000。
最小费用最大流,对于每个点拆成两个点限流即可
program run;
var
tot,n,m,i,j,k,a,b,c:longint;
maxn,ans:int64;
root,last:array [0..401] of longint;
dis:array [0..401] of int64;
cost:array [0..80001] of int64;
dl,next,point,flow:array [0..80001] of longint;
function anti (now:longint):longint;
begin
if now and 1 = 1 then exit(now+1)
else exit(now-1);
end;
procedure connect (u,v,f,c:longint);
begin
inc(tot);
point[tot]:=v;
flow[tot]:=f;
cost[tot]:=c;
next[tot]:=root[u];
root[u]:=tot;
end;
procedure maxflow;
begin
ans:=0;
repeat
fillchar(dis,sizeof(dis),63);
dis[1]:=0;
tot:=1;
dl[1]:=1;
i:=1;
while i<=tot do
begin
k:=root[dl[i]];
while k<>0 do
begin
if (flow[k]>0)and(dis[point[k]]>dis[dl[i]]+cost[k]) then
begin
dis[point[k]]:=dis[dl[i]]+cost[k];
inc(tot);
dl[tot]:=point[k];
last[point[k]]:=k;
end;
k:=next[k];
end;
inc(i);
end;
if dis[0]=dis[2*n] then break;
maxn:=maxlongint;
i:=2*n;
while i<>1 do
begin
if maxn>flow[last[i]] then maxn:=flow[last[i]];
i:=point[anti(last[i])];
end;
ans:=ans+maxn*dis[2*n];
i:=2*n;
while i<>1 do
begin
flow[last[i]]:=flow[last[i]]-maxn;
flow[anti(last[i])]:=flow[anti(last[i])]+maxn;
i:=point[anti(last[i])];
end;
until false;
writeln(flow[root[2*n]],' ',ans);
end;
begin
assign(input,'run.in');
reset(input);
assign(output,'run.out');
rewrite(output);
read(n,m);
tot:=0;
for i:=2 to n-1 do
begin
connect(i*2-1,i*2,1,0);
connect(i*2,i*2-1,0,0);
end;
connect(1,2,maxlongint div 10,0);
connect(2,1,0,0);
connect(2*n-1,2*n,maxlongint div 10,0);
connect(2*n,2*n-1,0,0);
for i:=1 to m do
begin
read(a,b,c);
connect(a*2,b*2-1,1,c);
connect(b*2-1,a*2,0,-c);
end;
maxflow;
close(input);
close(output);
end.
Elaxia为了优化晨跑训练计划,利用最小费用最大流算法设计了一套满足耐力和路线多样性的跑步路线,以实现训练周期最长且路径总距离最短的目标。
535

被折叠的 条评论
为什么被折叠?



