题目链接: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 ", ans); 72 } 73 return 0; 74 }