洛谷 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)
小明去一个国家旅游。这个国家有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.