Description
Bobo 有一个 n 个点,m 条边的有向无环图(即对于任意点 v,不存在从点 v 开始、点 v 结束的路径)。
为了方便,点用 1,2,…,n 编号。 设 count(x,y) 表示点 x 到点 y 不同的路径数量(规定 count(x,x)=0),Bobo 想知道

除以 (109+7) 的余数。
其中,ai,bj 是给定的数列。
Input
输入包含不超过 15 组数据。
每组数据的第一行包含两个整数 n,m (1≤n,m≤105).
接下来 n 行的第 i 行包含两个整数 ai,bi (0≤ai,bi≤109).
最后 m 行的第 i 行包含两个整数 ui,vi,代表一条从点
ui 到 vi 的边 (1≤ui,vi≤n)。
Output
对于每组数据,输出一个整数表示要求的值。
Sample Input
3 3
1 1
1 1
1 1
1 2
1 3
2 3
2 2
1 0
0 2
1 2
1 2
2 1
500000000 0
0 500000000
1 2
Sample Output
4 4250000014
方案数的统计,拓扑排序一下,从后往前累加,把∑count(i,j)*b[j]算出来,最后乘上对应的a[i]即可。
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define loop(i,j,k) for (int i = j;i != -1; i = k[i]) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r #define ff first #define ss second #define mp(i,j) make_pair(i,j) #define pb push_back #define pii pair<int,LL> #define in(x) scanf("%d", &x); using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-9; const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int N = 1e5 + 10; int T, n, m, x, y; int a[N], b[N], ans[N]; int ft[N], nt[N], u[N], in[N], sz; int main() { while (scanf("%d%d", &n, &m) != EOF) { rep(i, 1, n) { scanf("%d%d", &a[i], &b[i]); ft[i] = -1, in[i] = 0; ans[i] = 0; } sz = 0; rep(i, 1, m) { scanf("%d%d", &x, &y); u[sz] = x; nt[sz] = ft[y]; ft[y] = sz++; in[x]++; } LL res = 0; queue<int> p; rep(i, 1, n) if (!in[i]) p.push(i); while (!p.empty()) { int q = p.front(); p.pop(); loop(i, ft[q], nt) { (ans[u[i]] += (ans[q] + b[q]) % mod) %= mod; if (!--in[u[i]]) p.push(u[i]); } } rep(i, 1, n) (res += 1LL * a[i] * ans[i] % mod) %= mod; printf("%lld\n", res); } return 0; }