zoukankan      html  css  js  c++  java
  • bzoj1907: 树的路径覆盖(树形DP)

      一眼题...

      f[i][0]表示在i连接一个子树的最小值,f[i][1]表示在i连接两个子树的最小值,随便转移...

      样例挺强的1A了美滋滋...

    UPD:学习了2314的写法之后短了好多T T

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=500010, inf=1e9;
    struct poi{int too, pre;}e[maxn];
    int n, T, tot, x, y;
    int f[maxn][2], last[maxn];
    void read(int &k)
    {
        int f=1; k=0; char c=getchar();
        while(c<'0' || c>'9') c=='-' && (f=-1), c=getchar();
        while(c<='9' && c>='0') k=k*10+c-'0', c=getchar();
        k*=f;
    }
    inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
    inline int min(int a, int b){return a<b?a:b;}
    void dfs(int x, int fa) 
    {
        f[x][1]=maxn; f[x][0]=1; int sum=0;
        for(int i=last[x], too;i;i=e[i].pre)
        if((too=e[i].too)!=fa)
        {
            dfs(too, x);
            f[x][1]=min(f[x][1]+min(f[too][1], f[too][0]), f[x][0]+f[too][0]-1);
            f[x][0]=min(f[x][0]+min(f[too][1], f[too][0]), sum+f[too][0]);
            sum+=min(f[too][0], f[too][1]);
        }
    }
    int main()
    {
        read(T);
        while(T--)
        {
            read(n); memset(last, 0, (n+1)<<2); tot=0; 
            for(int i=1;i<n;i++) read(x), read(y), add(x, y), add(y, x);
            dfs(1, 0); printf("%d
    ", min(f[1][1], f[1][0]));
        }
    }
    View Code

    旧代码:

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=500010, inf=1e9;
    struct poi{int too, pre;}e[maxn];
    int n, T, tot, x, y;
    int f[maxn][2], last[maxn];
    void read(int &k)
    {
        int f=1; k=0; char c=getchar();
        while(c<'0' || c>'9') c=='-' && (f=-1), c=getchar();
        while(c<='9' && c>='0') k=k*10+c-'0', c=getchar();
        k*=f;
    }
    inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
    inline int min(int a, int b){return a<b?a:b;}
    void dfs(int x, int fa) 
    {
        int mn1=inf, mn2=inf, mni1=0, mni2=0, tmp=1; f[x][0]=0; f[x][1]=-1; 
        for(int i=last[x], too;i;i=e[i].pre)
        if((too=e[i].too)!=fa) 
        {
            dfs(too, x);
            f[x][0]+=min(f[too][1], f[too][0]); 
            if(f[too][0]==min(f[too][1], f[too][0])) tmp=0;
            if(f[too][0]-min(f[too][1], f[too][0])<mn1) mn1=f[too][0]-min(f[too][1], f[too][0]), mni1=too;
            else if(f[too][0]-min(f[too][1], f[too][0])<mn2) mn2=f[too][0]-min(f[too][1], f[too][0]), mni2=too;
        }
        f[x][0]+=tmp; 
        if(!(f[x][0]-tmp)) {f[x][0]=1; f[x][1]=inf; return;}
        if(mn2==inf) {f[x][1]=inf; return;}
        for(int i=last[x], too;i;i=e[i].pre)
        if((too=e[i].too)!=fa) 
        {
            if(too==mni1 || too==mni2) f[x][1]+=f[too][0]; 
                else f[x][1]+=min(f[too][1], f[too][0]);
        }
    }
    int main()
    {
        read(T);
        while(T--)
        {
            read(n); memset(last, 0, (n+1)<<2); tot=0; 
            for(int i=1;i<n;i++) read(x), read(y), add(x, y), add(y, x);
            dfs(1, 0); printf("%d
    ", min(f[1][1], f[1][0]));
        }
    }
    View Code
  • 相关阅读:
    Why we should overwrite the hashCode() when we overwrite the equals()
    static dictionary methods of text compression
    xtrabackup热备主库(带gtid),实时在线还原备库
    容器提示没有这个:libaio.so.1
    ORACLE账户提示EXPIRED(GRACE)问题
    mysql批量插入测试数据
    记录一下一个脚本化修改sudo提权
    mysql从别的库dump数据下来,然后导入不同名字的其它库
    记一个mysql最简单的清理其二进制的过程
    查看当前数据库正在执行的事件
  • 原文地址:https://www.cnblogs.com/Sakits/p/8007243.html
Copyright © 2011-2022 走看看