洛谷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串,全 ...
随机推荐
- [Angular] Provide Feedback to Progress Events with Angular’s HttpRequest Object
In some cases your application might need to upload large amounts of data, such as files. Obviously ...
- Android用canvas画哆啦A梦
先上图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/diss ...
- error[No partition metadata for topic test-1 due to kafka.common.LeaderNotAvailableException]
http://stackoverflow.com/questions/23228222/running-into-leadernotavailableexception-when-using-kafk ...
- setsockopt 设置socket
1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO ...
- 官方文档 Upgrading Elasticsearch
Upgrading Elasticsearch Before upgrading Elasticsearch: Consult the breaking changes docs. Use the E ...
- Vmware Workstation及Centos6.8 的安装
转自:http://www.mamicode.com/info-detail-1462939.html 一.什么是Vmware Workstation Vmware Workstation是Vmwar ...
- Combobox下拉框两级联动
下拉框的两级联动是我们开发中经常遇到一种情况.比如一个学生管理系统中,根据年级.科目及姓名查询学生考试成绩,年级和科目都是硬盘中的有限数据(数据库)而学生则可以有用户手动指定,这时在数据库中有年级和科 ...
- 持久层框架Clone
Clone框架:http://www.52chloe.com/Wiki/Document/3324802610879266816 Clone框架支持多种数据库,我用的是sql server 基本查询: ...
- 转:利用 T-sql 的从句 for xml path('') 实现多行合并到一行, 并带有分隔符
http://blog.csdn.net/rav009/article/details/50723307 T-sql 有一个for xml path('')的从句能把多行结果合并到一行,并成为xml ...
- 手工清理win7系统C盘的技巧
在我们日常使用电脑的过程中,随着使用的时候越久,大家就会发现电脑的运行速度变的越慢了,大家都知道很多系统东西一般都会安装在C盘,系统在运行的时候就会不断的产生垃圾文件以及其他我们根本用不到的文件,这样 ...