两道拓扑排序的问题

多久没写东西了啊。。。。

两道拓扑排序Liv.1的题。。。。方法是一样的~~

《拓扑排序·二》

题目:http://hihocoder.com/contest/hiho81/problem/1

一个电脑网路,单向边,如果存在边u->v,那么u的病毒会感染到v。

要点,不存在环!那么如果u的入度=0的话,那么u中的病毒数不会再变化。

想到拓扑排序。不断删去入度为0的点。每次删去节点u,如果存在u->v,那么病毒数

num[v] += num[u]。问题解决。

(用queue实现拓扑排序很方便~~)

代码:

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn = 100000 + 10;
 5 const int mod = 142857;
 6 int n, m, k;
 7 int num[maxn], in[maxn];
 8 vector<int> G[maxn];
 9 
10 int solve(){
11     queue<int> q;
12 
13     int ans = 0;
14     for( int i = 1; i <= n; ++i ){
15         if(!in[i]){
16             //cout << "i: " << i << endl;
17             q.push(i);
18         }
19     }
20 
21     while(!q.empty()){
22         int u = q.front(); q.pop();
23         ans = ( ans + num[u] )%mod;
24 
25         for( int i = 0; i < G[u].size(); ++i ){
26             int v = G[u][i];
27             in[v]--; num[v] = (num[u] + num[v])%mod;
28             if(!in[v])
29                   q.push(v);
30         }
31     }
32 
33     return ans;
34 }
35 
36 int main(){
37     scanf("%d%d%d", &n, &m, &k);
38 
39     memset( num, 0, sizeof(num) );
40     int u, v;
41     for( int i = 0; i < k; ++i ){
42         scanf("%d", &u);
43         num[u]++;
44     }
45 
46     memset( in, 0, sizeof(in) );
47     for( int i = 0; i < m; ++i ){
48         scanf("%d%d", &u, &v);
49         G[u].push_back(v); in[v]++;
50     }
51 
52     int ans = solve();
53     printf("%d
", ans);
54 
55     return 0;
56 }
View Code

《hiho一下 第八十一周》

题目:http://hihocoder.com/contest/hiho81/problem/1

方法相同,建图稍微难点。。。

代码:

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn = 100000 + 10;
 5 const int mod = 142857;
 6 int n, m;
 7 vector<int> in[maxn];
 8 int s[maxn], ru[maxn], num[maxn];
 9 vector<int> e[maxn], G[maxn];
10 
11 void init(){
12     for( int i = 0; i < maxn; ++i )
13       in[i].clear(), e[i].clear(), G[i].clear();
14     memset( s, 0, sizeof(s) );
15     memset( ru, 0, sizeof(ru) );
16     memset( num, 0, sizeof(num) );
17 }
18 
19 void solve(){
20       queue<int> q;
21       for( int i = 0; i <= n; ++i ){
22           if(!ru[i])
23              q.push(i);
24       }
25 
26       while(!q.empty()){
27             int u = q.front(); q.pop();
28             for( int i = 0; i < G[u].size(); ++i ){
29                   int v = G[u][i];
30                   ru[v]--, num[v] = (num[v] + num[u])%mod;
31                   if(!ru[v])
32                         q.push(v);
33             }
34       }
35 }
36 
37 void print(){
38       printf("%d", num[1]);
39       for( int i = 2; i <= n; ++i ){
40             printf(" %d", num[i]);
41       }
42       printf("
");
43 }
44 
45 int main(){
46     //freopen("1.in", "r", stdin);
47     int T;
48     scanf("%d", &T);
49 
50     while(T--){
51         init();
52         scanf("%d%d", &n, &m);
53 
54         int u, v, k;
55         s[0] = -1, num[0] = 1;
56         for( int i = 0; i < m; ++i ){
57             scanf("%d", &u);
58             e[0].push_back(u);
59         }
60 
61         for( int i = 1; i <= n; ++i ){
62             scanf("%d%d", &u, &k);
63             s[i] = u; in[u].push_back(i);
64             for( int j = 0; j < k; ++j ){
65                  scanf("%d", &u);
66                  e[i].push_back(u);
67             }
68         }
69 
70         //build graph
71         for( int i = 0; i <= n; ++i ){
72             for( int j = 0; j < e[i].size(); ++j ){
73                 int sg = e[i][j];
74                 for( int p = 0; p < in[sg].size(); ++p ){
75                      int v = in[sg][p]; ru[v]++;
76                      G[i].push_back(v);
77                 }
78             }
79         }
80         //output();
81 
82         solve();
83         print();
84     }
85 
86     return 0;
87 }
View Code
原文地址:https://www.cnblogs.com/zhazhalovecoding/p/5150561.html