1804: 有向无环图

Posted SJY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1804: 有向无环图相关的知识,希望对你有一定的参考价值。

1804: 有向无环图

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 341  Solved: 152
[Submit][Status][Web Board]

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
4
250000014

思路:拓扑排序+dp;
按照拓扑将点权合并就可以了。
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<iostream>
 5 #include<math.h>
 6 #include<queue>
 7 #include<vector>
 8 using namespace std;
 9 typedef  long long LL;
10 LL mod = 1e9+7;
11 LL dp[100005];
12 int cnt[100005];
13 LL a[100005];
14 LL b[100005];
15 vector<int>vec[100005];
16 queue<int>que;
17 int main(void)
18 {
19         int n,m;
20         while(scanf("%d %d",&n,&m)!=EOF)
21         {
22                 int i,j;LL ask ;
23                 while(!que.empty())
24                         que.pop();
25                 for(i = 0; i < 100005; i++)
26                         vec[i].clear();
27                 memset(cnt,0,sizeof(cnt));
28                 memset(dp,0,sizeof(dp));
29                 for(i = 1; i <= n; i++)
30                 {
31                         scanf("%lld %lld",&a[i],&b[i]);
32                 }
33                 while(m--)
34                 {
35                         int x,y;
36                         scanf("%d %d",&x,&y);
37                         cnt[y]++;
38                         vec[x].push_back(y);
39                 }
40                 for(i = 1; i <= n; i++)
41                 {
42                         if(cnt[i] == 0)
43                         {
44                                 que.push(i);
45                         }
46                 }
47                 while(!que.empty())
48                 {
49                     int x = que.front();
50                     que.pop();
51                     for(i = 0;i < vec[x].size();i++)
52                     {
53                         int y = vec[x][i];
54                         cnt[y] --;
55                         if(cnt[y] == 0)
56                             que.push(y);
57                         dp[y] = dp[y]+a[x]*b[y]%mod;
58                         dp[y]%=mod;
59                         a[y] = a[y] + a[x];
60                         a[y]%=mod;
61                         ask = dp[y];
62                     }
63                 }ask = 0;
64                 for(i = 1;i <= n;i++)
65                 {
66                     ask = ask + dp[i];
67                     ask %= mod;
68                 }
69                 printf("%lld\n",ask);
70         }
71         return 0;
72 }

 

 

以上是关于1804: 有向无环图的主要内容,如果未能解决你的问题,请参考以下文章

csu oj 1804: 有向无环图 (dfs回溯)

CSU 1804 - 有向无环图 - [树形DP]

CSU 1804: 有向无环图(拓扑排序)

[CSUOJ1804]有向无环图(树dp)

有向无环图

有向无环图