hihoCoder1175 拓扑排序·二 拓扑排序

题目链接:

http://hihocoder.com/problemset/problem/1175

题意:

n个点,m条边,有k个点是病毒源,这些病毒源可以传递给所有相邻节点一次,问最终病毒的总数

思路:

考虑每个点最终的病毒数是多少,就是它的所有前驱结点的病毒数的和,

按照拓扑排序的顺序去扩展病毒数量,这样相当于所有节点只走了一遍就出了结果

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define MS(a) memset(a,0,sizeof(a))
 5 #define MP make_pair
 6 #define PB push_back
 7 const int INF = 0x3f3f3f3f;
 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 9 inline ll read(){
10     ll x=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 //////////////////////////////////////////////////////////////////////////
16 const int maxn = 1e5+10;
17 const int mod = 142857;
18 
19 int a[maxn],in[maxn];
20 vector<int> g[maxn];
21 
22 int main(){
23     int n,m,k;
24     cin >> n >> m >> k;
25     for(int i=1; i<=k; i++){
26         int u = read();
27         a[u]++;
28     }
29     for(int i=0; i<m; i++){
30         int u,v; scanf("%d%d",&u,&v);
31         in[v]++;
32         g[u].push_back(v);
33     }
34 
35     queue<int> q;
36     for(int i=1; i<=n; i++){
37         if(in[i] == 0) q.push(i);
38     }
39     int ans = 0;
40     while(!q.empty()){
41         int u = q.front(); q.pop();
42         ans = (ans+a[u])%mod;
43         for(int i=0; i<(int)g[u].size(); i++){
44             int v = g[u][i];
45             in[v]--;
46             a[v] = (a[v]+a[u])%mod;
47             if(in[v] == 0) q.push(v);
48         }
49     }
50     cout << ans << endl;
51 
52 
53     return 0;
54 }
原文地址:https://www.cnblogs.com/yxg123123/p/6955674.html