[luogu4201][bzoj1063]设计路线【树形DP】
题目描述
Z国坐落于遥远而又神奇的东方半岛上,在小Z的统治时代公路成为这里主要的交通手段。Z国共有n座城市,一些城市之间由双向的公路所连接。非常神奇的是Z国的每个城市所处的经度都不相同,并且最多只和一个位于它东边的城市直接通过公路相连。Z国的首都是Z国政治经济文化旅游的中心,每天都有成千上万的人从Z国的其他城市涌向首都。为了使Z国的交通更加便利顺畅,小Z决定在Z国的公路系统中确定若干条规划路线,将其中的公路全部改建为铁路。我们定义每条规划路线为一个长度大于1的城市序列,每个城市在该序列中最多出现一次,序列中相邻的城市之间由公路直接相连(待改建为铁路)。并且,每个城市最多只能出现在一条规划路线中,也就是说,任意两条规划路线不能有公共部分。当然在一般情况下是不可能将所有的公路修建为铁路的,因此从有些城市出发去往首都依然需要通过乘坐长途汽车,而长途汽车只往返于公路连接的相邻的城市之间,因此从某个城市出发可能需要不断地换乘长途汽车和火车才能到达首都。我们定义一个城市的“不便利值”为从它出发到首都需要乘坐的长途汽车的次数,而Z国的交通系统的“不便利值”为所有城市的不便利值的最大值,很明显首都的“不便利值”为0。小Z想知道如何确定规划路线修建铁路使得Z国的交通系统的“不便利值”最小,以及有多少种不同的规划路线的选择方案使得“不便利值”达到最小。当然方案总数可能非常大,小Z只关心这个天文数字modQ后的值。注意:规划路线1-2-3和规划路线3-2-1是等价的,即将一条规划路线翻转依然认为是等价的。两个方案不同当且仅当其中一个方案中存在一条规划路线不属于另一个方案。
题解
我们可以发现这种修建的方式最终形成的关系很想树链剖分中的轻重链,每个点到首都的不便利值其实就是走过的轻边的数量。对于这个题来说显然我们需要轻边的数量尽可能小,树链剖分中这个数目不超过logn个,所以对于这个题来说第一问的答案一定不超过logn,而这个题与树链剖分还存在不同,因为还可以V型覆盖,就是路径的起终点在同一个点的子树中,对于一个点来说,最多有一个V型覆盖,也最多只有一个简单路径覆盖。
设\(f[n][m][i]\)表示以n为根的子树中,答案不超过m,与儿子有i条重边相连的方案数。
其中\(i<=2\)
定义\(g[v][0]\)表示从\(n\)出发走轻边到达父亲节点
\[g[v][0]=f[v][m-1][0]+f[v][m-1][1]+f[v][m-1][2]\]
\(g[v][1]\)表示从n出发走重边到达父亲节点
\[g[v][1]=f[v][m-1][0]+f[v][m-1][1]\]
(没有f[v][m-1][2]是因为如果是走重边上来,那么v这个点下面的儿子中只可能有一个儿子是重边)
ac代码
#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define N 100005
using namespace std;
template <typename T>
inline void read(T &x) {
x = 0; T fl = 1;
char ch = 0;
while (ch < '0' || ch > '9') {
if (ch == '-') fl = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
x *= fl;
}
struct edge {
int to, nt;
}E[N << 1];
int cnt, n, m;
ll f[N][30][4], g[N][5], p;
int H[N];
void add_edge(int u, int v) {
E[++ cnt] = (edge){v, H[u]};
H[u] = cnt;
}
ll Mod(ll x) {
if (x && x % p == 0) return p;
else return x % p;
}
void dfs(int u, int fa) {
for (int i = 0; i <= 20; i ++) f[u][i][0] = 1;
for (int e = H[u]; e; e = E[e].nt) {
int v = E[e].to;
if (v == fa) continue;
dfs(v, u);
for (int j = 0; j <= 20; j ++) {
if (j) g[v][0] = Mod(f[v][j - 1][0] + f[v][j - 1][1] + f[v][j - 1][2]);
g[v][1] = Mod(f[v][j][0] + f[v][j][1]);
f[u][j][2] = Mod(f[u][j][1] * g[v][1] + f[u][j][2] * g[v][0]);
f[u][j][1] = Mod(f[u][j][0] * g[v][1] + f[u][j][1] * g[v][0]);
f[u][j][0] = Mod(f[u][j][0] * g[v][0]);
}
}
}
int main() {
read(n); read(m); read(p);
if (m < n - 1) {
printf("-1\n-1\n");
return 0;
}
for (int i = 1; i <= m; i ++) {
int u, v;
read(u); read(v);
add_edge(u, v);
add_edge(v, u);
}
ms(f, 0);
dfs(1, -1);
for (int i = 0; i <= 20; i ++) {
if (f[1][i][0] + f[1][i][1]+ f[1][i][2] > 0) {
printf("%d\n", i);
printf("%lld\n", (f[1][i][0] + f[1][i][1] + f[1][i][2]) % p);
return 0;
}
}
printf("-1\n-1\n");
return 0;
}
[luogu4201][bzoj1063]设计路线【树形DP】的更多相关文章
- hdu-----(4514)湫湫系列故事——设计风景线(树形DP+并查集)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- BZOJ1063 NOI2008 道路设计 树形DP
题目传送门: BZOJ 题意精简版:给出一棵树,在一种方案中可以将树的若干链上的所有边的边权改为$0$,但需要保证任意两条链之间没有交点.问最少的一种方案,使得从根节点到其他节点经过的边的边权和的最大 ...
- HDU 4514 湫湫系列故事――设计风景线 (树形DP)
题意:略. 析:首先先判环,如果有环直接输出,用并查集就好,如果没有环,那么就是一棵树,然后最长的就是树的直径,这个题注意少开内存,容易超内存, 还有用C++交用的少一些,我用G++交的卡在32764 ...
- 洛谷 P4201 设计路线 [NOI2008] 树形dp
正解:树形dp 解题报告: 大概是第一道NOI的题目?有点激动嘻嘻 然后先放个传送门 先大概港下这题的题意是啥qwq 大概就是给一棵树,然后可以选若干条链把链上的所有边的边权变成0,但是这些链不能有交 ...
- P4201-[NOI2008]设计路线【结论,树形dp】
正题 题目链接:https://www.luogu.com.cn/problem/P4201 题目大意 给出\(n\)个点的一棵树开始所有边都是白色,选出若干条没有公共点的路径将上面所有边变为黑色. ...
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- HDU 4514 湫湫系列故事——设计风景线(并查集+树形DP)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) To ...
- 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)
根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
随机推荐
- CrackMe-005全破详解(图文+源码)--上篇
逆向破解 | 逆向 | 逆向分析 | CrackMe | Crack | CrackMe5 | CrackMe05 前言 CrackMe005,都说比较变态,很多人给放过去了,但是我还是决定上了它,既 ...
- eclipse添加maven环境
一.打开eclipse,选择Window->preference,如下图所示 二.Maven-> installation->add,见下图: 三.选择Directory,选择mav ...
- 基本的排序算法C++实现(插入排序,选择排序,冒泡排序,归并排序,快速排序,最大堆排序,希尔排序)
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/8529525.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- js控制css时注意
font-size:10px--------e.style.fontSize="10px " 属性名:font-size--------fontSize; 属性值:10px---- ...
- 软件工程驻足篇章:第十七周和BugPhobia团队漫长的道别
0x01 :序言 I am a slow walker, but I never walk backwards. 成长于被爱,学着爱人 成长的故事 也是年少的星期六结束的故事 就仿佛我和BugPhob ...
- 《Gogoing》Alpha版会议总结
一.开会的过程 首先大家对自己的任务进行了汇报,然后大家就当前最需要解决的问题提出解决方案,最后相互鼓励,相互帮助,探讨下一步该怎么做. 二.讨论的问题 百度地图API代码和界面代码为什么对接不上? ...
- springboot整合fastJson遇到重定向问题
通过网上教程使用springboot整合fastJson后遇到页面重定向问题(使用的springboot版本是2.0.2.RELEASE ,其他的版本可能不会出现以下问题),如下图: 我的项目结构如下 ...
- Python小笔记
最近在学习Python 以前也学过一些编程语言 但是都不扎实 由于工作的原因 需要学习Python做一些处理 刚开始学习总有多多少少的不适应 从今天开始打算将我在学习中遇到的困难以及疑问记录下来 ...
- 开发中CollectionUtils处理集合
1.org.apache.commons.collections.CollectionUtils; 使用这个工具类,帮我们处理一些集合的操作,非常方便 //取并集public void testUni ...
- vue-devtools 的安装和使用
vue-devtools的安装与使用 一.在github上下载压缩包,github下载地址:https://github.com/vuejs/vue-devtools 二.解压到本地的某盘 三.用你的 ...