hihocoder 1175
拓扑排序
拓扑只适用于 有向无环图中,这个指的是
1.有向的,不是那种双向可走的
2.无环,并不是不存在环,而是一定要有一个没有其他点指向这个点的点,
题目大意:一个有向无环图n个点,m个边,其中随机往里面投k个病毒,病毒传下个点时会复制以至于原先的点病毒数量不变,而下个点得到的病毒数量和原先的点的病毒数量相等,问最后,所有点一共多少个病毒;
分析:该题中,如果用dfs写的话,有种斐波那契的感觉,数据大过不了;
所以用到拓扑
附上代码,有注释
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <map> 7 #include <iomanip> 8 #include <algorithm> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <vector> 13 //const int maxn = 1e5+5; 14 #define ll long long 15 #define MAX INT_MAX 16 #define FOR(i,a,b) for( int i = a;i <= b;++i) 17 #define MOD 142857 18 using namespace std; 19 20 vector <int> vec[110000]; //用来存路径,例如a能到b,那么vec[a].push_back(c); 21 int v[110000]; //用来存这个点的病毒个数
int indegree[110000]; //用来存还有多少个点能到这个点(开始的时候indegree[k]==0,就代表k是起点 22 int n,m ,k,woc,a,b,head,temp,ans; 23 queue<int>que; //用来存从删去的点(接下来开始计算v[]的点 24 int main() 25 { 26 // freopen("D:\\common_text\\code_stream\\in.txt","r",stdin); 27 // freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); 28 cin>>n>>m>>k; 29 FOR(i,1,k) 30 { 31 cin>>woc; 32 v[woc]++; 33 } 34 FOR(i,1,m) 35 { 36 cin>>a>>b; 37 vec[a].push_back(b); 38 indegree[b]++; 39 } 40 for(int i=1;i<=n;++i) 41 { 42 if(indegree[i]==0) 43 { 44 que.push(i); 45 } 46 } 47 while(!que.empty()) 48 { 49 head=que.front(); 50 que.pop(); 51 ans+=v[head]; 52 ans%=MOD; 53 for(int i=0;i<vec[head].size();++i) 54 { 55 temp=vec[head][i]; 56 v[temp]+=v[head]; 57 v[temp]%=MOD; 58 if(--indegree[temp]==0) //已经没有点到这个点了 59 { 60 que.push(temp); 61 } 62 } 63 } 64 cout<<ans%MOD; 65 }