题目描述

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】的更多相关文章

  1. hdu-----(4514)湫湫系列故事——设计风景线(树形DP+并查集)

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  2. BZOJ1063 NOI2008 道路设计 树形DP

    题目传送门: BZOJ 题意精简版:给出一棵树,在一种方案中可以将树的若干链上的所有边的边权改为$0$,但需要保证任意两条链之间没有交点.问最少的一种方案,使得从根节点到其他节点经过的边的边权和的最大 ...

  3. HDU 4514 湫湫系列故事――设计风景线 (树形DP)

    题意:略. 析:首先先判环,如果有环直接输出,用并查集就好,如果没有环,那么就是一棵树,然后最长的就是树的直径,这个题注意少开内存,容易超内存, 还有用C++交用的少一些,我用G++交的卡在32764 ...

  4. 洛谷 P4201 设计路线 [NOI2008] 树形dp

    正解:树形dp 解题报告: 大概是第一道NOI的题目?有点激动嘻嘻 然后先放个传送门 先大概港下这题的题意是啥qwq 大概就是给一棵树,然后可以选若干条链把链上的所有边的边权变成0,但是这些链不能有交 ...

  5. P4201-[NOI2008]设计路线【结论,树形dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4201 题目大意 给出\(n\)个点的一棵树开始所有边都是白色,选出若干条没有公共点的路径将上面所有边变为黑色. ...

  6. HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  7. HDU 4514 湫湫系列故事——设计风景线(并查集+树形DP)

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...

  8. 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)

    根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...

  9. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

随机推荐

  1. [C#]SQLite执行效率优化结论

    一.如要使用SQLite,可以从Visual Studio中的“程序包管理器控制台”输入以下命令完成安装: PM> Install-Package System.Data.SQLite.Core ...

  2. 【react】使用 create-react-app 构建基于TypeScript的React前端架构----上

    写在前面 一直在探寻,那优雅的美:一直在探寻,那精湛的技巧:一直在探寻,那简单又直白,优雅而美丽的代码. ------ 但是在JavaScript的动态类型.有时尴尬的自动类型转换,以及 “0 == ...

  3. 印象深刻的bug

    测试中测到一个印象比较深刻的bug,问题出现在web端的电商平台,展示商品的时候每点击一个商品相应的url=~/productid.html,如果知道productid可以直接在url输入跳转到商品详 ...

  4. Jmeter(GUI模式)教程

    前些天,领导让我做接口的压力测试.What??我从未接触过这方面,什么都不知道,一脸蒙.于是我从学习jmeter开始入手. 现在记录下来jmeter的使用步骤,希望能对大家有所帮助. 一.安装Jmet ...

  5. FormData

    1. 概述FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利. 2. 构造函数创建一个formData对象 ...

  6. 【2016.4.6】结对编程 终章 THE END

  7. dxteam团队项目终审报告

    一. 团队成员的简介和个人博客地址 M1阶段 http://www.cnblogs.com/dxteam/p/3991514.html M2阶段 新成员 邓亚梅 http://www.cnblogs. ...

  8. Android之JSON格式数据解析

    查看原文:http://blog.csdn.net/hantangsongming/article/details/42234293 JSON:JavaScript 对象表示法(JavaScript ...

  9. java中定时执行任务

    现在项目中用到需要定时去检查文件是否更新的功能.timer正好用于此处. 用法很简单,new一个timer,然后写一个timertask的子类即可. 代码如下: package comz.autoup ...

  10. Hibernate的初次使用

    使用hibernate的四个步骤:第一:创建一个hibernate.cfg.xml.<!DOCTYPE hibernate-configuration PUBLIC "-//Hiber ...