首页 > 代码库 > 洛谷P1137 旅行计划 拓扑排序 图论

洛谷P1137 旅行计划 拓扑排序 图论

洛谷P1137 旅行计划
拓扑排序   图论
在拓扑排序中把每个点能够浏览的点加上去
但是这样会有重复
因为我们要求一个点向前多能浏览的点
所以我们只要求连向这个点中能向前浏览的点数最多的点
这一路就是能浏览的最多的点
然后这个点就相当于是拓扑排序中使该点的入度为 0 的那个点
用那个点来更新当前点就行了

 

 1 #include <bits/stdc++.h> 
 2 #define For(i,j,k) for(int i=j;i<=k;i++)
 3 #define LL long long 
 4 using namespace std ;
 5 
 6 const int N = 100011,M = 200011 ; 
 7 int n,m,cnt ; 
 8 struct edge{
 9     int to,pre ; 
10 }e[M]; 
11 int head[N],ru[N],dis[N] ; 
12 
13 inline int read() 
14 {
15     int x = 0 , f = 1 ; 
16     char ch = getchar() ; 
17     while(ch<0||ch>9) { if(ch==-) f = -1 ; ch = getchar(); } 
18     while(ch>=0&&ch<=9) { x = x * 10+ch-48 ; ch = getchar(); } 
19     return x * f ; 
20 }
21 
22 inline void add(int x,int y) 
23 {
24     e[cnt].to = y ; 
25     e[cnt].pre = head[x] ; 
26     head[x] = cnt++ ; 
27 }
28 
29 inline void tuopu() 
30 {
31     int u,v ; 
32     queue<int> Q ; 
33     For(i,1,n) if(!ru[ i ]) Q.push( i ) ; 
34     while(!Q.empty()) {
35         u = Q.front() ; 
36         Q.pop() ; 
37         for(int i=head[u];~i;i=e[i].pre) {
38             v = e[ i ].to ; 
39             ru[ v ]-- ; 
40             if(ru[ v ]==0) {
41                 Q.push(v) ; 
42                 dis[ v ]+=dis[ u ] ; 
43             }
44         }
45     }
46 }
47 
48 int main() 
49 {
50     n = read() ; m = read() ; 
51     int x,y ; 
52     For(i,0,n) head[ i ] = -1 ; 
53     For(i,1,m) {
54         x = read() ; y = read() ; 
55         add(x,y) ; ru[ y ]++ ; 
56     } 
57     For(i,1,n) dis[ i ] = 1 ; 
58     tuopu() ; 
59     For(i,1,n) printf("%d\n",dis[ i ]) ; 
60     return 0 ; 
61 } 

 

洛谷P1137 旅行计划 拓扑排序 图论