多久没写东西了啊。。。。
两道拓扑排序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 }
《hiho一下 第八十一周》
题目:http://hihocoder.com/contest/hiho81/problem/1
方法相同,建图稍微难点。。。
代码:
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; 7 vector<int> in[maxn]; 8 int s[maxn], ru[maxn], num[maxn]; 9 vector<int> e[maxn], G[maxn]; 10 11 void init(){ 12 for( int i = 0; i < maxn; ++i ) 13 in[i].clear(), e[i].clear(), G[i].clear(); 14 memset( s, 0, sizeof(s) ); 15 memset( ru, 0, sizeof(ru) ); 16 memset( num, 0, sizeof(num) ); 17 } 18 19 void solve(){ 20 queue<int> q; 21 for( int i = 0; i <= n; ++i ){ 22 if(!ru[i]) 23 q.push(i); 24 } 25 26 while(!q.empty()){ 27 int u = q.front(); q.pop(); 28 for( int i = 0; i < G[u].size(); ++i ){ 29 int v = G[u][i]; 30 ru[v]--, num[v] = (num[v] + num[u])%mod; 31 if(!ru[v]) 32 q.push(v); 33 } 34 } 35 } 36 37 void print(){ 38 printf("%d", num[1]); 39 for( int i = 2; i <= n; ++i ){ 40 printf(" %d", num[i]); 41 } 42 printf("\n"); 43 } 44 45 int main(){ 46 //freopen("1.in", "r", stdin); 47 int T; 48 scanf("%d", &T); 49 50 while(T--){ 51 init(); 52 scanf("%d%d", &n, &m); 53 54 int u, v, k; 55 s[0] = -1, num[0] = 1; 56 for( int i = 0; i < m; ++i ){ 57 scanf("%d", &u); 58 e[0].push_back(u); 59 } 60 61 for( int i = 1; i <= n; ++i ){ 62 scanf("%d%d", &u, &k); 63 s[i] = u; in[u].push_back(i); 64 for( int j = 0; j < k; ++j ){ 65 scanf("%d", &u); 66 e[i].push_back(u); 67 } 68 } 69 70 //build graph 71 for( int i = 0; i <= n; ++i ){ 72 for( int j = 0; j < e[i].size(); ++j ){ 73 int sg = e[i][j]; 74 for( int p = 0; p < in[sg].size(); ++p ){ 75 int v = in[sg][p]; ru[v]++; 76 G[i].push_back(v); 77 } 78 } 79 } 80 //output(); 81 82 solve(); 83 print(); 84 } 85 86 return 0; 87 }
时间: 2024-10-25 07:53:46