# BZOJ 1063 道路设计NOI2008

http://www.lydsy.com/JudgeOnline/problem.php?id=1063

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];
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 }
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(){
52     for (int i=1;i<=n;i++) fa[i]=i;
53     for (int i=1;i<=m;i++){
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\n-1\n");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\n",i);
65              printf("%lld\n",((f[1][i][0]+f[1][i][1])%Mod+f[1][i][2])%Mod);
66              return 0;
67             }
68     }
69 }

posted @ 2016-06-23 15:25  GFY  阅读(252)  评论(0编辑  收藏  举报