算法:搜索
分析:这道题只要记住一点就可以,即设置每个点开始被访问的时间为st[i],完成这个点(包括它的子节点)的访问时间为finish[i],那么j是i的子节点的充要条件就是st[j]>=st[i]且finish[j]<=finish[i],只要分析出这一点再把属于这种情况的赛道统计一下就OK了。
分析:这道题只要记住一点就可以,即设置每个点开始被访问的时间为st[i],完成这个点(包括它的子节点)的访问时间为finish[i],那么j是i的子节点的充要条件就是st[j]>=st[i]且finish[j]<=finish[i],只要分析出这一点再把属于这种情况的赛道统计一下就OK了。
思考:初始状态写在DFS的开始,末状态写在DFS的结束。
program NDK1160;
const
maxn=10000;
maxm=100000;
type
atp=record
y,next,dis:longint;
end;
var
n,m,tot:longint;
ans,final:int64;
first,into:array [0..maxn] of longint;
a:array [0..maxn,0..2] of longint;
map:array [0..maxm] of atp;
procedure init;
var
i,x,y,t:longint;
begin
tot:=0;
final:=0;
ans:=0;
readln(n,m);
for i:=1 to n-1 do
begin
readln(x,y,t);
inc(into[y]);
map[i].y:=y;
map[i].next:=first[x];
map[i].dis:=t;
first[x]:=i;
end;
end;
function dfs(x,w:longint):longint;
var
t:longint;
begin
a[x,0]:=w;
inc(tot);
a[x,1]:=tot;
t:=first[x];
while t>0 do
begin
dfs(map[t].y,w+map[t].dis);
t:=map[t].next;
end;
inc(tot);
a[x,2]:=tot;
end;
procedure main;
var
i,x,y:longint;
begin
for i:=1 to m do
begin
readln(x,y);
if (a[x,1]<=a[y,1]) and (a[x,2]>=a[y,2]) then
begin
inc(ans);
inc(final,a[y,0]-a[x,0]);
end;
end;
end;
begin
assign(input,'NDK1160.in'); reset(input);
assign(output,'NDK1160.out'); rewrite(output);
init;
dfs(1,0);
main;
writeln(ans);
writeln(final);
close(input); close(output);
end.