首页 > 技术文章 > csu oj 1804: 有向无环图 (dfs回溯)

Recoder 2016-09-13 15:09 原文

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1804

中文题意就不说了。

dfs从底到根回溯即可,看代码应该能清楚。

 1 //#pragma comment(linker, "/STACK:102400000, 102400000")
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <ctime>
10 #include <list>
11 #include <set>
12 #include <map>
13 using namespace std;
14 typedef long long LL;
15 typedef pair <int, int> P;
16 const int N = 1e5 + 5;
17 struct Edge {
18     int next, to;
19 }edge[N];
20 int head[N], tot, in[N];
21 LL a[N], b[N], ans, d[N], mod = 1e9 + 7; //d[i]表示b[i.son]*count[i,j]+b[i]
22 bool vis[N];
23 
24 void init(int n) {
25     for(int i = 1; i <= n; ++i) {
26         head[i] = -1;
27         in[i] = 0;
28         vis[i] = false;
29     }
30     tot = 0;
31     ans = 0;
32 }
33 
34 inline void add_edge(int u, int v) {
35     edge[tot].next = head[u];
36     edge[tot].to = v;
37     head[u] = tot++;
38 }
39 
40 void dfs(int u) {
41     d[u] = b[u] % mod;
42     for(int i = head[u]; ~i; i = edge[i].next) {
43         int v = edge[i].to;
44         if(!vis[v]) { //说明这个点以及子树没访问
45             dfs(v);
46             vis[v] = true;
47         }
48         ans = (ans + a[u] * d[v] % mod) % mod;
49         d[u] = (d[v] + d[u]) % mod;
50     }
51 }
52 
53 int main()
54 {
55     int n, m, u, v;
56     while(scanf("%d %d", &n, &m) != EOF) {
57         for(int i = 1; i <= n; ++i) {
58             scanf("%lld %lld", a + i, b + i);
59         }
60         init(n);
61         for(int i = 1; i <= m; ++i) {
62             scanf("%d %d", &u, &v);
63             add_edge(u, v);
64             ++in[v];
65         }
66         for(int i = 1; i <= n; ++i) {
67             if(!in[i]) { //入度为0
68                 dfs(i);
69             }
70         }
71         printf("%lld\n", ans);
72     }
73     return 0;
74 }

 

推荐阅读