您的位置:首页 > 其它

洛谷 P1137 旅行计划

2017-08-09 14:22 316 查看
题目大意:

小明去一个国家旅游。这个国家有N个城市,编号为1~N,并且有M条道路连接着,小明准备从其中一个城市出发,并只往东走到城市i停止。

所以他就需要选择最先到达的城市,并制定一条路线以城市i为终点,使得线路上除了第一个城市,每个城市都在路线前一个城市东面,并且满足这个前提下还希望游览的城市尽量多。

让你为求出以城市i为终点最多能够游览多少个城市。

对于20%的数据,N ≤ 100;

对于60%的数据,N ≤ 1000;

对于100%的数据,N ≤ 100000,M ≤ 200000。

题解:

拓扑排序:

很明显这题就是对城市做一个拓扑排序。

找到一个城市就让他加上“能到达他的城市”的个数;

但是我们会发现有重复

如何避免?

因为拓扑,所以当我们走到了一个城市后,他所有指向的城市都会入度-1;

这时

他所指向的城市有2种情况:

①入度不为0,则说明还有城市会通向它,并且那个城市的浏览数比当前城市的浏览数多或相等(因为他在排序中更靠后),所以我们不加;

反之,它入度为0,则说明后面的点没有通向他的城市,且当前城市的浏览数是所有能通向它的城市的最多的,我们就可以加上它。且将这个点扔到队列中。

一开始每个点都答案为1,因为它本身是一个。

我们将一开始入度就为0的点扔到队列里去做。

时间复杂度:O(M+N)

const
maxn=100001;
maxm=200001;
var
rd,ans:array [0..maxn] of longint;
q,gt,next,list:array [0..maxm] of longint;
x,y,i,n,m:longint;

procedure add(aa,bb,cc:longint);
begin
gt[aa]:=cc;
next[aa]:=list[bb];
list[bb]:=aa;
end;

procedure find;
var
head,tail,i:longint;
begin
head:=0; tail:=0;
for i:=1 to n do
begin
ans[i]:=1;
if rd[i]=0 then
begin
inc(tail);
q[tail]:=i;
end;
end;
while head<tail do
begin
inc(head);
i:=list[q[head]];
while i>0 do
begin
dec(rd[gt[i]]);
if rd[gt[i]]=0
then begin
inc(tail);
ans[gt[i]]:=ans[gt[i]]+ans[q[head]];
q[tail]:=gt[i];
end
e5c1
;
i:=next[i];
end;
end;
end;

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