zoukankan      html  css  js  c++  java
  • hdu 4714 Tree2cycle dp

    用树形dp做的,dp[t][i]表示t及其孩子入度都已经小于等于2并且t这个节点的入度等于i的最优解。

    那么转移什么的自己想想就能明白了。

    关键在于这个题目会暴栈,所以我用了一次bfs搜索出节点的顺序,然后再计算。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=1e6+9;
    struct
    {
        int to,next;
    }e[maxn*2];
    int head[maxn],lon;
    bool text[maxn];
    void edgeini()
    {
        memset(head,-1,sizeof(head));
        lon=-1;
    }
    void edgemake(int from,int to)
    {
        e[++lon].to=to;
        e[lon].next=head[from];
        head[from]=lon;
    }
    int dp[maxn][3];
    int from[maxn];
    void dfs(int t)
    {
        int k;
        int a1=10,a2=10,ret=0,u;
        for(k=head[t];k!=-1;k=e[k].next)
        {
            u=e[k].to;
            if(u==from[t]) continue;
            ret++;
            dp[t][0]+=dp[u][2]+2;
            if(dp[u][1]-dp[u][2]<a1)
            {
                a2=a1;
                a1=dp[u][1]-dp[u][2];
            }
            else if(dp[u][1]-dp[u][2]<a2)
            a2=dp[u][1]-dp[u][2];
        }
        if(ret>=1)
        dp[t][1]=max(0,dp[t][0]+a1-2);
        else
        dp[t][1]=dp[t][0];
        if(ret>=2)
        dp[t][2]=max(0,dp[t][0]+a1+a2-4);
        else
        dp[t][2]=dp[t][1];
    //    cout<<0<<endl;
    }
    
    int que[maxn];
    void bfs()
    {
        int front=1,end=0;
        que[++end]=1;
        text[1]=1;
        while(front<=end)
        {
            int t=que[front++];
            for(int k=head[t];k!=-1;k=e[k].next)
            {
                int u=e[k].to;
                if(!text[u])
                {
                    from[u]=t;
                    text[u]=1;
                    que[++end]=u;
                }
            }
        }
        for(int i=end;i>=1;i--)
        dfs(que[i]);
    }
    
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(dp,0,sizeof(dp));
            edgeini();
            int n;
            scanf("%d",&n);
            for(int i=1,from,to;i<n;i++)
            {
                scanf("%d %d",&from,&to);
                edgemake(from,to);
                edgemake(to,from);
            }
            memset(text,0,sizeof(text));
            bfs();
            printf("%d
    ",dp[1][2]+1);
        }
        return 0;
    }
    


  • 相关阅读:
    芯片测试
    【转】悬浮的对话框
    imagebutton 设置点击和按压效果
    imagebutton 设置了src属性的图片更换
    侧滑实现
    使用自定义的AlertDialog。
    [转]Dialog
    【转】webview的几个问题
    webview 播放H5视频问题 黑屏 只有声音没有画面
    【转】Android HTML5 Video视频标签自动播放与自动全屏问题解决
  • 原文地址:https://www.cnblogs.com/pangblog/p/3310762.html
Copyright © 2011-2022 走看看