hihocoder 1175

  拓扑排序

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 }

 

posted @ 2019-04-19 01:59  阿斯水生产线  阅读(182)  评论(0编辑  收藏  举报