zoukankan      html  css  js  c++  java
  • 树形DP Choosing Capital for Treeland

    给你一棵有向树,需要选定一个点为capital,满足翻转边数最小

    思路:先求出1为capital 的答案,然后向下更新孩子节点 

    dp[i]=dp[i-1]+judge(i);

    #include<iostream>  
    #include<cstdio>  
    #include<cstring>  
    #include<algorithm>  
    #include<cmath>  
    #include<queue>  
    #include<stack>  
    #include<vector>  
    #include<set>  
    #include<map>  
      
    #define L(x) (x<<1)  
    #define R(x) (x<<1|1)  
    #define MID(x,y) ((x+y)>>1)  
      
    #define bug printf("hihi
    ")  
      
    #define eps 1e-8  
    typedef __int64 ll;  
      
    using namespace std;  
    #define INF 0x3f3f3f3f  
    #define N 200005  
      
    int dp[N];  
    int n;  
      
    struct stud{  
      int to,ne,len;  
    }e[N*2];  
    int head[N];  
    int num;  
      
    inline void add(int u,int v,int len)  
    {  
        e[num].to=v;  
        e[num].len=len;  
        e[num].ne=head[u];  
        head[u]=num++;  
    }  
      
    void dfs(int u,int pre)  
    {  
        dp[u]=0;  
        for(int i=head[u];i!=-1;i=e[i].ne)  
        {  
            int to=e[i].to;  
            if(to==pre) continue;  
            dfs(to,u);  
            dp[u]+=dp[to]+e[i].len;  
        }  
    }  
      
    void dfsup(int u,int pre)  
    {  
        for(int i=head[u];i!=-1;i=e[i].ne)  
        {  
            int to=e[i].to;  
            if(to==pre) continue;  
            dp[to]=dp[u];  
            if(e[i].len) dp[to]--;  
            else dp[to]++;  
            dfsup(to,u);  
        }  
    }  
      
    int main()  
    {  
        int i,j;  
        while(~scanf("%d",&n))  
        {  
            memset(head,-1,sizeof(head));  
            num=0;  
            int u,v;  
            i=n-1;  
            while(i--)  
            {  
                scanf("%d%d",&u,&v);  
                add(u,v,0);  
                add(v,u,1);  
            }  
            dfs(1,-1);  
            dfsup(1,-1);  
            int ans=INF;  
            for(i=1;i<=n;i++)  
                ans=min(ans,dp[i]);  
            printf("%d
    ",ans);  
            vector<int>temp;  
            temp.clear();  
            for(i=1;i<=n;i++)  
                if(dp[i]==ans) temp.push_back(i);  
            for(i=0;i<temp.size();i++)  
            {  
                if(i) printf(" ");  
                printf("%d",temp[i]);  
            }  
            printf("
    ");  
        }  
        return 0;  
    }  
    View Code
  • 相关阅读:
    vim 插件之commentary
    vim-进入插入模式快捷键
    adb logcat 使用
    操作excel脚本练习
    python-openpyxl安装
    python-excel操作之xlrd
    adb-端口被占用解决办法(win)
    打不开微信分享的链接
    在BUG分支下创建分支,开发后合并到bus分支
    css缓存问题
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7302537.html
Copyright © 2011-2022 走看看