bzoj1945: [Ceoi2007]Royaltreasury

来源:互联网 发布:java json转换 编辑:程序博客网 时间:2024/06/01 20:36

传送门
裸的树形dp。
f[i][0/1]表示当前位置没用/用了
转移暴力就可以了
然后就是喜闻乐见的高精度模板了。

#include<cmath>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 1005#define ll long long#define mo 1000000000using namespace std;struct bignum{    ll a[25];    bignum(int x=0){        memset(a,0,sizeof(a));        if (!x) return;        a[1]=x; a[0]=1;    }    friend bignum operator +(bignum a,bignum b){        bignum c;        c.a[0]=max(a.a[0],b.a[0]);        for (int i=1;i<=c.a[0];i++) c.a[i]=a.a[i]+b.a[i];        for (int i=1;i<=c.a[0];i++){            c.a[i+1]+=c.a[i]/mo;            c.a[i]%=mo;        }        if (c.a[c.a[0]+1]) c.a[0]++;        return c;    }    friend bignum operator *(bignum a,bignum b){        bignum c;        for (int i=1;i<=a.a[0];i++){            ll x=0;            for (int j=1;j<=b.a[0];j++){                x+=c.a[i+j-1]+a.a[i]*b.a[j];                c.a[i+j-1]=x%mo;                x/=mo;            }            c.a[i+b.a[0]]=x;        }        c.a[0]=a.a[0]+b.a[0];        while (c.a[0]&&!c.a[c.a[0]]) c.a[0]--;        return c;    }    void print(){        printf("%lld",a[a[0]]);        for (int i=a[0]-1;i>0;i--)            printf("%09lld",a[i]);        puts("");    }};vector<int> e[N];int f[N][2];bignum g[N][2];int n,x,y,z;void dfs(int x,int y){    if (f[x][y]!=-1) return;    f[x][y]=0; g[x][y]=bignum(0);    if (!e[x].size()&&y) return;    if (!y){        g[x][y]=bignum(1);        for (int i=0;i<e[x].size();i++){            dfs(e[x][i],0); dfs(e[x][i],1);            if (f[e[x][i]][0]>f[e[x][i]][1]){                f[x][y]=f[x][y]+f[e[x][i]][0];                g[x][y]=g[x][y]*g[e[x][i]][0];            }            else{                f[x][y]=f[x][y]+f[e[x][i]][1];                if (f[e[x][i]][0]!=f[e[x][i]][1])                    g[x][y]=g[x][y]*g[e[x][i]][1];                else g[x][y]=g[x][y]*(g[e[x][i]][0]+g[e[x][i]][1]);            }        }        return;    }    int p; bignum q;    for (int i=0;i<e[x].size();i++)        dfs(e[x][i],0),dfs(e[x][i],1);    for (int i=0;i<e[x].size();i++){        p=0; q=bignum(1);        for (int j=0;j<e[x].size();j++)            if (j!=i){                if (f[e[x][j]][0]>f[e[x][j]][1]){                    p=p+f[e[x][j]][0];                    q=q*g[e[x][j]][0];                }                else{                    p=p+f[e[x][j]][1];                    if (f[e[x][j]][0]!=f[e[x][j]][1])                        q=q*g[e[x][j]][1];                    else q=q*(g[e[x][j]][0]+g[e[x][j]][1]);                }            }            else{                p=p+f[e[x][j]][0]+1;                q=q*g[e[x][j]][0];            }        if (p>f[x][y]){            f[x][y]=p; g[x][y]=bignum(0);        }        if (p==f[x][y])            g[x][y]=g[x][y]+q;    }}int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++){        scanf("%d%d",&x,&y);        while (y--){            scanf("%d",&z);            e[x].push_back(z);        }    }    memset(f,-1,sizeof(f));    dfs(1,0);    dfs(1,1);    if (f[1][0]<f[1][1])        f[1][0]=f[1][1],g[1][0]=0;    if (f[1][0]==f[1][1])        g[1][0]=g[1][0]+g[1][1];    printf("%d\n",f[1][0]);    g[1][0].print();}
原创粉丝点击