题目链接:
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 }