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

两道拓扑排序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\n", ans);
54 
55     return 0;
56 }
View Code

相关文章:

猜你喜欢
  • 2022-12-23
  • 2022-01-17
  • 2022-12-23
  • 2022-12-23
  • 2021-10-22
相关资源
相似解决方案