zoukankan      html  css  js  c++  java
  • [bzoj1063][Noi2008]道路设计【树形dp】

    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=1063
    【题解】
      首先有一个结论,不便利值的最大值是logN级别的。
      那么随便dp一下就行了。
      时间复杂度O(NlogN)
      

    /* --------------
        user Vanisher
        problem bzoj-1063
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    N       100010
    # define    K       30
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    struct node{
        int data,next;
    }e[N*2];
    int f[N][3],cnt,head[N],place,up,n,m;
    ll g[N][K][3],P,ans;
    void build(int u, int v){
        e[++place].data=v; e[place].next=head[u]; head[u]=place;
        e[++place].data=u; e[place].next=head[v]; head[v]=place;
    }
    void dfs(int x, int fa){
        f[x][0]=0; cnt++;
        for (int ed=head[x]; ed!=0; ed=e[ed].next)
            if (e[ed].data!=fa){
                dfs(e[ed].data,x);
                f[x][2]=min(max(f[x][2],f[e[ed].data][2]+1),max(f[x][1],f[e[ed].data][1]));
                f[x][1]=min(max(f[x][1],f[e[ed].data][2]+1),max(f[x][0],f[e[ed].data][1]));
                f[x][0]=max(f[x][0],f[e[ed].data][2]+1);
            }
        f[x][1]=min(f[x][0],f[x][1]);
        f[x][2]=min(f[x][1],f[x][2]);
    }
    void work(int x, int fa){
        for (int i=0; i<=up; i++)
            g[x][i][0]=1;
        for (int ed=head[x]; ed!=0; ed=e[ed].next)
            if (e[ed].data!=fa){
                work(e[ed].data,x);
                for (int i=0; i<=up; i++){
                    ll f1=g[e[ed].data][i][1]+g[e[ed].data][i][0],f2;
                    if (i>0)    
                        f2=(g[e[ed].data][i-1][0]+g[e[ed].data][i-1][1]+g[e[ed].data][i-1][2])%P;
                        else f2=0;
                    g[x][i][2]=(g[x][i][1]*f1+g[x][i][2]*f2)%P;
                    g[x][i][1]=(g[x][i][0]*f1+g[x][i][1]*f2)%P;
                    g[x][i][0]=(g[x][i][0]*f2)%P;
                }
            }
    }
    int main(){
        n=read(), m=read(), P=read();
        for (int i=1; i<=m; i++)
            build(read(),read());
        cnt=0;
        memset(f,inf,sizeof(f));
        dfs(1,0);
        if (cnt!=n){
            printf("-1
    -1
    ");
            return 0;
        }
        up=f[1][2];
        work(1,0);
        ans=(g[1][f[1][2]][0]+g[1][f[1][2]][1]+g[1][f[1][2]][2])%P;
        printf("%d
    %lld
    ",f[1][2],ans);
        return 0;
    }
    
  • 相关阅读:
    异步底层代码实现邮件发送
    MongoDB+Echarts+DWebSocket
    celery定时任务+redis有序集合实现实时访问人数
    位运算+数据库两种方式实现中间件权限操作
    cocoapod 引入url
    pdf转xml
    Flutter项目安卓下载地址
    ios Mac 利用SVN进行cocoapod私有库的使用
    KVO
    类别和类扩展的区别
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135969.html
Copyright © 2011-2022 走看看