题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804

Bobo 有一个 n 个点,m 条边的有向无环图(即对于任意点 v,不存在从点 v 开始、点 v 结束的路径)。
为了方便,点用 1,2,…,n 编号。 设 count(x,y) 表示点 x 到点 y 不同的路径数量(规定 count(x,x)=0),Bobo 想知道
 
 
除以 (10 9+7) 的余数。
其中,a i,b j 是给定的数列。
 

Input

输入包含不超过 15 组数据。
每组数据的第一行包含两个整数 n,m (1≤n,m≤10 5).
接下来 n 行的第 i 行包含两个整数 a i,b i (0≤a i,b i≤10 9).
最后 m 行的第 i 行包含两个整数 u i,v i,代表一条从点 u i 到 v i 的边 (1≤u i,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

题解:

首先,假如我们计算$\sum\limits_{i = 1}^n {\sum\limits_{j = 1}^n {\left( {count\left( {i,j} \right) \times a_i \times b_j } \right)} } $

这个的时候,固定一个点i,枚举j进行计算的话,就有:

$a_i \times \left[ {\sum\limits_{j = 1}^n {\left( {count\left( {i,j} \right) \times b_j } \right)} } \right]$

我们不妨设$dp\left[ i \right] = \sum\limits_{j = 1}^n {\left( {count\left( {i,j} \right) \times b_j } \right)} $

那么,最后的${\rm{ans}} = \sum\limits_{i = 1}^n {\left\{ {a_i \times \left[ {\sum\limits_{j = 1}^n {\left( {count\left( {i,j} \right) \times b_j } \right)} } \right]} \right\}} $

问题来了,状态转移方程是什么?

假设对于点i,它有K个子节点,就有:

$dp\left[ i \right] = \sum\limits_{k = 1}^K {\left( {b_k + dp\left[ k \right]} \right)} $

(根据题意无环图,则存在 Edge(i→k) 就一定不存在一条路径从k点到i点,所以计算dp[k]时就一定不会涉及到dp[i])

另外,本题如果不是有向无环图而是一棵树的话,很显然,直接从树根往下dfs计算每个节点i的dp[i]即可,

但是现在有向无环图,可能出现如下情况:

这样一来,如果主函数里单单dfs(1)或者单单dfs(2)都不能把整个图上所有节点的dp[i]都计算到,

因此要把所有in-degree[i]==0的节点i都dfs(i).

AC代码:

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL; const LL MOD=1e9+;
const int maxn=1e5+; int n,m;
int indegree[maxn];
LL a[maxn],b[maxn];
LL dp[maxn]; struct Edge{
int u,v;
Edge(int u,int v){this->u=u,this->v=v;}
};
vector<Edge> E;
vector<int> G[maxn];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int u,int v)
{
E.push_back(Edge(u,v));
G[u].push_back(E.size()-);
} LL dfs(int u)
{
if(dp[u]!=-) return dp[u]; dp[u]=;
for(int i=,_size=G[u].size();i<_size;i++)
{
Edge &e=E[G[u][i]]; int v=e.v;
dp[u]=(dp[u]+b[v]+dfs(v))%MOD;
}
return dp[u];
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<=n;i++) scanf("%d%d",&a[i],&b[i]); init(,n); //邻接表初始化
memset(indegree,,sizeof(indegree));
for(int i=,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
indegree[v]++;
} memset(dp,-,sizeof(dp));
for(int i=;i<=n;i++)
{
if(indegree[i]==) dfs(i);
} LL ans=;
for(int i=;i<=n;i++) ans = ( ans + (dp[i]*a[i]) % MOD ) % MOD; printf("%lld\n",ans);
}
}

CSU 1804 - 有向无环图 - [(类似于)树形DP]的更多相关文章

  1. CSU 1804: 有向无环图 拓扑排序 图论

    1804: 有向无环图 Submit Page   Summary   Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 716    ...

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

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在 ...

  3. csu 1804 有向无环图

    题目地址 分析:从复杂度来看,一定不可能是枚举和来计算.1e5的规模来看,应该是复杂度比较合适. 我是这么想的,对于三个点,假设1->2有a种走法,2->3有b种走法.那么1->3应 ...

  4. 【拓扑】【宽搜】CSU 1084 有向无环图 (2016湖南省第十二届大学生计算机程序设计竞赛)

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1804 题目大意: 一个有向无环图(DAG),有N个点M条有向边(N,M<=105 ...

  5. 【学习笔记】有向无环图上的DP

    手动博客搬家: 本文发表于20180716 10:49:04, 原地址https://blog.csdn.net/suncongbo/article/details/81061378 首先,感谢以下几 ...

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

    题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1804 中文题意就不说了. dfs从底到根回溯即可,看代码应该能清楚. //#pragma ...

  7. 湖南省第十二届大学生计算机程序设计竞赛 B 有向无环图 拓扑DP

    1804: 有向无环图 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 187  Solved: 80[Submit][Status][Web Board ...

  8. select 函数实现 三种拓扑结构 n个客户端的异步通信 (完全图+线性链表+无环图)

    一.这里只介绍简单的三个客户端异步通信(完全图拓扑结构) //建立管道 mkfifo open顺序: cl1 读 , cl2 cl3 向 cl1写 cl2 读 , cl1 cl3 向 cl2写 cl3 ...

  9. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

随机推荐

  1. Window系统、主函数和窗体函数这三者之间的关系

    理解Window系统.主窗体.窗体函数这三者之间的关系,对于编写Windows程序十分重要. 主函数和窗体函数都是由Windows系统来调用的函数.仅仅只是主函数是程序启动之后.系统首先调用的函数: ...

  2. Maven------报错:Error resolving version for plugin

    配置Maven插件时报错:Error resolving version for plugin 'org.springframeboot.boot:spring-boot-maven-plugin' ...

  3. Explaining Delegates in C# - Part 2 (Events 1)

    In my previous post, I spoke about a few very basic and simple reasons of using delegates - primaril ...

  4. Linux下安装配置MySQL

    一.删除原来的MySQL 在安装前要先确定系统是否已经安装了其他版本的MySQL,如已安装其他版本的MySQL,需先删除后再安装新版本. 1. 执行yum命令,删除MySQL的lib库,服务文件 yu ...

  5. Ansible Playbook 使用循环语句

    如下,with_items 是循环的对象,with_items 是 python list 数据结构,task 会循环读取 list 里面的值,key 的名称是 item [root@localhos ...

  6. STL——迭代器与traits编程技法

    一.迭代器 1. 迭代器设计思维——STL关键所在 在<Design Patterns>一书中对iterator模式定义如下:提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素 ...

  7. iOS - 截屏,view截图的基本方法

    推荐一个第三方好用的框架:SDScreenshotCapture #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice cur ...

  8. 《转载》WIN10 64位系统 32位Python2.7 PIL安装

    http://blog.csdn.net/kanamisama0/article/details/53960281 首先安装这个真的出了好多问题,之前装过一次PIL也失败了,就一直没管,今天刚好找了机 ...

  9. Windows 7笔记本创建wifi热点供手机上网教程

    Windows 7笔记本创建wifi热点供手机上网教程 | 浏览:60606 | 更新:2012-07-19 11:48 | 标签:笔记本 wifi 1 2 3 4 5 6 7 分步阅读 用智能手机的 ...

  10. GitHub----初学习(一)

    刚开始学习GitHub,在这借鉴一下别人的总结,http://youngxhui.github.io/2016/05/03/GitHub-for-Windows%E4%BD%BF%E7%94%A8%E ...