洛谷P1137 旅行计划 解题报告(拓扑排序+DP)
我看了一下其他大佬的题解,大部分都是拓扑排序加上DP。那么我想有的人是不明白为什么这么做的,拓扑排序有什么性质使得可以DP呢?下面我就提一下。
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。 (源自百度)
通俗的说就是,一张有向无环图的拓扑序可以使得任意的起点u,它的一个终点v,在序列中的顺序是u在前v在后
我下面先附上代码,然后在继续说明
#include<bits/stdc++.h>
using namespace std; const int maxn=100000+15;
int n,m,sum,tot;
int head[maxn],ru[maxn],ts[maxn],dp[maxn];
struct EDGE
{
int to;int next;
}edge[maxn<<2];
void add(int x,int y)
{
edge[++sum].next=head[x];
edge[sum].to=y;
head[x]=sum;
}
void topsort()
{
queue <int> q;
for (int i=1;i<=n;i++)
if (ru[i]==0) {
q.push(i);
ts[++tot]=i;
}
while (!q.empty())
{
int u=q.front();q.pop();
for (int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
ru[v]--;
if (ru[v]==0) {
q.push(v);ts[++tot]=v;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
ru[v]++;
}
topsort();
for (int i=1;i<=n;i++) dp[i]=1;
for (int i=1;i<=n;i++)
{
int u=ts[i];
for (int j=head[u];j;j=edge[j].next)
{
int v=edge[j].to;
dp[v]=max(dp[v],dp[u]+1);
}
}
for (int i=1;i<=n;i++)
printf("%d\n",dp[i]);
return 0;
}
仔细看DP部分,还记得DP需要满足什么原则吗?无后效性。如果不是在拓扑序中进行DP,会完全破坏无后效性(当然这也下面为什么有人用记忆化搜索的原因,记忆化搜索同样可以解决无后效性的问题)。正是因为拓扑序u在前,v在后的性质,这才选择使用拓扑排序,毕竟它的代码实现很轻松,而且运行时间也不差。
至于怎么求拓扑序,就是把入度为0(就是没有边把它作为终点)的点入队,并加入拓扑序。之后断掉以这个点为起点的边,即将这些边的终点的入度减一,直到队为空就好。
那么就是这些了,希望对大家有帮助
洛谷P1137 旅行计划 解题报告(拓扑排序+DP)的更多相关文章
- 洛谷P1137 旅行计划
P1137 旅行计划 题目描述 小明要去一个国家旅游.这个国家有N个城市,编号为1-N,并且有M条道路连接着,小明准备从其中一个城市出发,并只往东走到城市i停止. 所以他就需要选择最先到达的城市,并制 ...
- 洛谷 P1137 旅行计划 (拓扑排序+dp)
在DAG中,拓扑排序可以确定dp的顺序 把图的信息转化到一个拓扑序上 注意转移的时候要用边转移 这道题的dp是用刷表法 #include<bits/stdc++.h> #define RE ...
- 洛谷 P1137 旅行计划
旅行计划 待证明这样dp的正确性. #include <iostream> #include <cstdio> #include <cstring> #includ ...
- 洛谷——P1137 旅行计划
https://www.luogu.org/problem/show?pid=1137 题目描述 小明要去一个国家旅游.这个国家有N个城市,编号为1-N,并且有M条道路连接着,小明准备从其中一个城市出 ...
- 洛谷p1137旅行计划
题面 关于拓扑排序 因为这好几次考试的题目里都有在DAG中拓扑排序求最长/短路 txt说它非常的好用 就找了个题做了下 拓扑排序就是寻找图中所有的入度为零的点把他入队 然后再枚举它所有的连到的点,只要 ...
- 洛谷 P2680 运输计划 解题报告
P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- 洛谷1087 FBI树 解题报告
洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...
随机推荐
- 阅读《Android 从入门到精通》(15)——数字时钟
数字时钟(DigitalClock) java.lang.Object; android.view.View; android.widget.TextView; android.widget.Digi ...
- 【Allwinner ClassA20类库分析】 2.free pascal语法及结构简析
上一节介绍了Lazarus一般的开发操作流程,对于不熟悉pascal语言的朋友可能看的还是不大明确.不知道pascal代码里都应该包括什么或起什么作用.这回就简单地介绍下语法及代码文件的结构. ...
- STM32F407VG (四)时钟配置
1.STM32 F407VG 的starup_stm32f40_41xxx.s的例如以下位置调用 IMPORT SystemInit,之后调用main函数,所以 进入main函数时候就已经自己主动完毕 ...
- C#上传文件
QQ:1187362408 欢迎技术交流和学习 关于C#上传文件(产品开发): TODO: 1.文件大小不足500M(web.config配置直接处理) 2,文件大小超过500M(ASP.NET分段读 ...
- UVALive 4192/HDU 2959 Close Enough Computations 数学
Close Enough Computations Problem Description The nutritional food label has become ubiquitous. A sa ...
- Linux下DNS服务器搭建详解
Linux下DNS服务器搭建详解 DNS 即Domain Name System(域名系统)的缩写,它是一种将ip地址转换成对应的主机名或将主机名转换成与之相对应ip地址的一种机制.其中通过域名解析 ...
- Django之ORM数据库增删改查
总结:ORM的 查.增.删.改 - 查 - client - 有一个展示页面(xxx_show.html) - 这一个页面一输入执行后,get请求向server端发送 - 这个展示页面有添加按钮.删除 ...
- accept-language
Chrome: [zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4]Safari: [zh-tw]FF: [zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3 ...
- POJ 1182 食物链 (并查集解法)(详细注释)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 78510 Accepted: 23396 Description ...
- STM8S103-STVD建立汇编代码项目
转载:http://blog.csdn.net/u010093140/article/details/49983397 STVD本来就比较少人用,STVD汇编就更少人用了,不过STM8汇编我自己还是满 ...