zoukankan      html  css  js  c++  java
  • 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=f[pur][b-1][0]+f[pur][b-1][1]+f[pur][b-1][2]


    f[x][b][2]=f2*f[x][b][2]+f1*f[x][b][1]


    f[x][b][1]=f1*f[x][b][0]+f2*f[x][b][1]


    f[x][b][0]=f[x][b][0]*f2

    pur代表x的儿子

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define ll long long
     7 ll Mod;
     8 int first[200005],next[200005],go[200005],tot;
     9 int n,m,fa[200005];
    10 ll f[100005][12][3];
    11 int read(){
    12     int t=0,f=1;char ch=getchar();
    13     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    14     while ('0'<=ch&&ch<='9') {t=t*10+ch-'0';ch=getchar();}
    15     return t*f;
    16 }
    17 void insert(int x,int y){
    18         tot++;
    19         go[tot]=y;
    20         next[tot]=first[x];
    21         first[x]=tot;
    22 }
    23 void add(int x,int y){
    24         insert(x,y);insert(y,x);
    25 }
    26 int find(int x){
    27     if (fa[x]==x) return x;else return fa[x]=find(fa[x]);
    28 }
    29 ll get(ll x){
    30     if (x%Mod!=0) return x%Mod;
    31     if (x!=0) return Mod;
    32     return 0;
    33 }
    34 void dfs(int x,int b,int fa){
    35     f[x][b][0]=1;
    36     f[x][b][1]=0;
    37     f[x][b][2]=0;
    38     for (int i=first[x];i;i=next[i]){
    39         int pur=go[i];
    40         if (pur==fa) continue;
    41         dfs(pur,b,x);
    42         ll f1=(f[pur][b][0]+f[pur][b][1]);    
    43         ll f2;
    44         if (b) f2=f[pur][b-1][0]+f[pur][b-1][1]+f[pur][b-1][2];else f2=0;
    45         f[x][b][2]=get(f2*f[x][b][2]+f1*f[x][b][1]);
    46         f[x][b][1]=get(f1*f[x][b][0]+f2*f[x][b][1]);
    47         f[x][b][0]=get(f[x][b][0]*f2);
    48     }
    49 }
    50 int main(){
    51     n=read();m=read();Mod=read();
    52     for (int i=1;i<=n;i++) fa[i]=i;
    53     for (int i=1;i<=m;i++){
    54         int x=read(),y=read();
    55         add(x,y);
    56         int p=find(x),q=find(y);
    57         if (p!=q) fa[q]=p;    
    58     }
    59     for (int i=2;i<=n;i++)
    60         if (find(i)!=find(1)){printf("-1
    -1
    ");return 0;}
    61     for (int i=0;;i++){
    62         dfs(1,i,0);
    63         if (f[1][i][0]+f[1][i][1]+f[1][i][2]){
    64              printf("%d
    ",i);
    65              printf("%lld
    ",((f[1][i][0]+f[1][i][1])%Mod+f[1][i][2])%Mod);
    66              return 0;
    67             }
    68     }    
    69 }
  • 相关阅读:
    java 实现N进制转M进制
    BigInteger构造函数解析
    SpringBoot 实现前后端分离的跨域访问(CORS)
    python:[numpy] ndarray 与 list 互相转换
    PyTorch使用GPU的方法
    Matplotlib.pyplot 把画图保存为图片 指定图片大小
    python列表中的所有值转换为字符串,以及列表拼接成一个字符串
    python 读取中文文件名/中文路径
    在Python中使用LSTM和PyTorch进行时间序列预测(深度学习时序数据预测)
    记录分析python程序运行时间的几种方法
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5610925.html
Copyright © 2011-2022 走看看