[BZOJ]1063 道路设计(Noi2008)

  省选一试后的第一篇blog!

Description

  Z国坐落于遥远而又神奇的东方半岛上,在小Z的统治时代,公路成为这里主要的交通手段。Z国共有n座城市,一些城市之间由双向的公路所连接。非常神奇的是Z国的每个城市所处的经度都不相同,并且最多只和一个位于它东边的城市直接通过公路相连。Z国的首都是Z国政治经济文化旅游的中心,每天都有成千上万的人从Z国的其他城市涌向首都。为了使Z国的交通更加便利顺畅,小Z决定在Z国的公路系统中确定若干条规划路线,将其中的公路全部改建为铁路。我们定义每条规划路线为一个长度大于1的城市序列,每个城市在该序列中最多出现一次,序列中相邻的城市之间由公路直接相连(待改建为铁路)。并且,每个城市最多只能出现在一条规划路线中,也就是说,任意两条规划路线不能有公共部分。当然在一般情况下是不可能将所有的公路修建为铁路的,因此从有些城市出发去往首都依然需要通过乘坐长途汽车,而长途汽车只往返于公路连接的相邻的城市之间,因此从某个城市出发可能需要不断地换乘长途汽车和火车才能到达首都。我们定义一个城市的“不便利值”为从它出发到首都需要乘坐的长途汽车的次数,而Z国的交通系统的“不便利值”为所有城市的不便利值的最大值,很明显首都的“不便利值”为0。小Z想知道如何确定规划路线修建铁路使得Z国的交通系统的“不便利值”最小,以及有多少种不同的规划路线的选择方案使得“不便利值”达到最小。当然方案总数可能非常大,小Z只关心这个天文数字modQ后的值。注意:规划路线1-2-3和规划路线3-2-1是等价的,即将一条规划路线翻转依然认为是等价的。两个方案不同当且仅当其中一个方案中存在一条规划路线不属于另一个方案。

Input

  第一行包含三个正整数N、M、Q,其中N表示城市个数,M表示公路总数,N个城市从1~N编号,其中编号为1的是首都。Q表示上文提到的设计路线的方法总数的模数。接下来M行,每行两个不同的正数ai、bi表示有一条公路连接城市ai和城市bi。输入数据保证一条公路只出现一次。

Output

  包含两行。第一行为一个整数,表示最小的“不便利值”。第二行为一个整数,表示使“不便利值”达到最小时不同的设计路线的方法总数modQ的值。如果某个城市无法到达首都,则输出两行-1。

Sample Input

  5 4 100
  1 2
  4 5
  1 3
  4 1

Sample Output

  1
  10

HINT

  对于100%的数据,满足1≤N,M≤100000,1≤Q≤120000000,1≤ai,bi≤N。

Solution

  题面描述得相当别扭啊,小C也是看过discuss后才知道它给的是一座森林。

  正常来说学过树链剖分的人只要看到这一条件,题目就已经做完了。

  题目实际上要我们求的是,求一棵树的树链剖分方案,使得所有点到根的路径上所走的轻边数量的最大值最小。

  学过树链剖分的人都应该知道,如果按照重链剖分(即重边连向结点更多的子树)来划分一棵树,那么从某个点出发走到根节点最多只要走logN条重链。

  树剖复杂度的证明在此提一下,其实也很简单,设x个结点组成的树中,所有点到根路径上轻边数量最大值的最大值为f(x)。

  那么就有,由于f(x)是递增的,所以f(x)必定是从f((x-1)/2)+1转移得到的。

  所以转移式化简就是:,很显然f(N)是logN级别的。

  因此答案最大不会超过logN,而且这样形态的树是一棵二叉树。

  但实际上这道题所说的链剖不是真正意义上的链剖,划分出来的路径是可以拐弯的,因此答案会比logN更小一些,实际上在树的形态是三叉树的情况下答案达到最大,大概是log_3(N)级别。

  然后知道了以上这些结论我们可以非常容易地写出DP的状态和转移方程:

  设f[i][j][0/1]表示在结点i的子树中,答案为j,且该子树能否继续向上连边的链剖方案数。转移花log^2随便转移一下就行。

  最后判断答案的时候简单地根据该处的DP值是否为0来取最小值是不可行的,因为方案数很可能对Q取模等于0,所以这里有一个小技巧,就是方案数为Q的倍数的时候,将对Q取模的值设为Q即可。

  时间复杂度

#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
#define MN 100005
#define MS 12
using namespace std;
struct edge{int nex,to;}e[MN<<1];
int n,m,mod,pin;
int hr[MN],f[MN][2][MS];

inline int read()
{
    int n=0,f=1; char c=getchar();
    while (c<‘0‘ || c>‘9‘) {if(c==‘-‘)f=-1; c=getchar();}
    while (c>=‘0‘ && c<=‘9‘) {n=n*10+c-‘0‘; c=getchar();}
    return n*f;
}

inline void rw(int& x,int y) {x+=y; if(x>mod)x-=mod;}
inline int modu(ll x) {return !x?0:(x-1)%mod+1;}
inline void ins(int x,int y) {e[++pin]=(edge){hr[x],y}; hr[x]=pin;}

void dfs(int x,int fat)
{
    register int i,j,k;
    int g[3][MS],h[3][MS+5];
    memset(g,0,sizeof(g));
    memset(h,0,sizeof(h));
    g[0][0]=1;
    for (i=hr[x];i;i=e[i].nex)
    {
        if (e[i].to==fat) continue;
        dfs(e[i].to,x);
        for (j=0;j<MS;++j)
            for (k=0;k<MS;++k)
            {
                rw(h[2][max(j+1,k)],modu(1LL*g[2][k]*(f[e[i].to][0][j]+f[e[i].to][1][j])));
                rw(h[2][max(j,k)],modu(1LL*g[1][k]*f[e[i].to][0][j]));
                rw(h[1][max(j+1,k)],modu(1LL*g[1][k]*(f[e[i].to][0][j]+f[e[i].to][1][j])));
                rw(h[1][max(j,k)],modu(1LL*g[0][k]*f[e[i].to][0][j]));
                rw(h[0][max(j+1,k)],modu(1LL*g[0][k]*(f[e[i].to][0][j]+f[e[i].to][1][j])));
            }
        for (j=0;j<MS;++j)
            g[0][j]=h[0][j],h[0][j]=0,
            g[1][j]=h[1][j],h[1][j]=0,
            g[2][j]=h[2][j],h[2][j]=0;
    }
    for (i=0;i<MS;++i)
        f[x][0][i]=g[0][i],rw(f[x][0][i],g[1][i]),f[x][1][i]=g[2][i];
}

int main()
{
    register int i,x,y;
    n=read(); m=read(); mod=read();
    if (m!=n-1) return 0*printf("-1\n-1");
    for (i=1;i<=m;++i)
        x=read(),y=read(),
        ins(x,y),ins(y,x);
    dfs(1,0);
    for (i=0;i<MS;++i)
        if (f[1][0][i]||f[1][1][i])
            return 0*printf("%d\n%d",i,(f[1][0][i]+f[1][1][i])%mod);
}

Last Word

  心血来潮写了一下小D的mint,交上去竟然T了,好感度--,表示这模板不是很想再用了。

原文地址:https://www.cnblogs.com/ACMLCZH/p/8452438.html

时间: 2024-08-03 09:47:41

[BZOJ]1063 道路设计(Noi2008)的相关文章

BZOJ 1063 道路设计NOI2008

http://www.lydsy.com/JudgeOnline/problem.php?id=1063 题意:给你一棵树,也有可能是不连通的,把树分成几个链,求每个点到根经过的最大链数最小,而且要输出方案数. 思路:考虑dp,f[i][j]代表第i个节点,最大链数是j,那么有 f[i][j][0]代表已经向子树连接了0个链 f[i][j][1]代表已经向子树连接了1个链 f[i][j][2]代表已经向子树连接了2个链 这样转移就是 f1=f[pur][b][0]+f[pur][b][1] f2

【BZOJ 1063】 [Noi2008]道路设计

1063: [Noi2008]道路设计 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 691  Solved: 387 [Submit][Status] Description Z 国坐落于遥远而又神奇的东方半岛上,在小Z 的统治时代公路成为这里主要的交通手段.Z 国共有n 座城市,一些城市之间由双向的公路所连接.非常神奇的是Z 国的每个城市所处的经度都不相同,并且最多只和一个位于它东边的城市直接通过公路相连.Z 国的首都是Z 国政治经济文化旅

【NOI题解】【bzoj题解】NOI2008 bzoj1063 道路设计

@ACMLCZH学长出的毒瘤题T3.再也不是"善良"的出题人了. 题意:bzoj. 题解: 经典的树形DP题目,屡见不鲜了,然而我还是没有写出来. 这一类的题目有很多,例如这里的C题. 主要套路是把对儿子的枚举变成一个类似背包的转移方式,实现降复杂度. 需要注意的是某一个地方的DP值不能直接拿来判断是否有解,例如mod=1时,DP值全为0就没法判断了. 这里比较骚的操作是把mod的倍数变成mod,而0变成0,这样就不会漏判. #include<bits/stdc++.h>

【BZOJ 1061】 [Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 2066  Solved: 1282 [Submit][Status] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中

【BZOJ】1061: [Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3752  Solved: 2298[Submit][Status][Discuss] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要 Ai 个人. 布布通过了解得知,一共有M 类志

【BZOJ 1064】 [Noi2008]假面舞会

1064: [Noi2008]假面舞会 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 988  Solved: 507 [Submit][Status] Description 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方会把此编号告诉拿该面具的人.为了使舞会更有神秘感,主办方把面具分为k (k≥3)类,并使用特

【BZOJ】1064: [Noi2008]假面舞会(判环+gcd+特殊的技巧)

http://www.lydsy.com/JudgeOnline/problem.php?id=1064 表示想到某一种情况就不敢写下去了.... 就是找环的gcd...好可怕.. 于是膜拜了题解.. 和我想的差不多.. 首先发现这3几种情况: 1.一条或多条单链,那么最多有sum{单链长度}个面具,最少有3个面具 2.环.主要是大环套小环QAQ,显然我们只要小环就行了QAQ环的长度为标号差,gcd能满足这个性质,因此不管它.找出所有的环即可. 3.链相交.此时最大为相交链的长度差的gcd,最小

bzoj 1064【noi2008】假面舞会

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1064 给一个有向图染色,每个点的后继必须相同,问至少&至多有多少种染色方案 sol:  图由多个联通块组成,对于每个联通块,考虑以下3种情况: 如果有环,分为3类讨论 对于第一种简单环,答案一定是环长的约数 对于第二种有反向边的环,答案一定是两条链长差的约数 trick:将有向边化为无向边,正向边权为1,反向为-1 这样1,2可以一起做 对于第三种大环套小环,将小环缩点即可(gcd(a,b)

11月刷题总结

这是11月的坑...现在来填... noip考跪...希望省选rp++ (11月刷了不少水题... 动态规划+递推: [BZOJ]1072: [SCOI2007]排列perm(状压dp+特殊的技巧) [BZOJ]1068: [SCOI2007]压缩(dp) [BZOJ]1088: [SCOI2005]扫雷Mine(递推) [BZOJ]1096: [ZJOI2007]仓库建设(dp+斜率优化) [BZOJ]1037: [ZJOI2008]生日聚会Party(递推+特殊的技巧) [BZOJ]1009