zoukankan      html  css  js  c++  java
  • CodeForces 219D Choosing Capital for Treeland (树形DP)经典

    <题目链接>

    题目大意:

    给定一个有向树,现在要你从这颗树上选一个点,使得从这个点出发,到达树上其它所有点所需翻转的边数最小,输出最少需要翻转的边数,并且将这些符合条件的点输出。

    解题分析:

    比较经典的一种树形DP的模型。

    $dp1[u]$表示以$u$为根的子树中最少需要翻转的边数(即$u$走到子树中所有的点需要翻转的边数),$dp2[u]$表示u向父亲方向走,需要翻转的边数。

    $dp1$的转移方程很好写:$dp1[u]=dp1[u]+e[i].w$  (正向边$e[i].w=0$,反向边为1)

    $dp2$的转移方程通过图像也能够比较直观的得到:$dp2[v]=dp1[u]-dp1[v]-e[i].w+e[i^{1}].w+dp2[u];$

    #include <bits/stdc++.h>
    using namespace std;
    template<typename T>
    inline void read(T&x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){ if(c=='-')f=-1;c=getchar(); }
        while(c>='0' && c<='9'){ x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    const int N = 2e5+5;
    #define REP(i,s,t) for(int i=s;i<=t;i++)
    struct Edge{ int to,w,nxt; }e[N<<1];
    int n,cnt;
    int head[N],dp1[N],dp2[N];
    inline void add(int u,int v,int w){
        e[cnt]=(Edge){v,w,head[u] };head[u]=cnt++;
    }
    void dfs1(int u,int pre){
        for(int i=head[u];~i;i=e[i].nxt){
            int v=e[i].to;
            if(v==pre)continue;
            dfs1(v,u);
            dp1[u]+=dp1[v]+e[i].w;
        }
    }
    void dfs2(int u,int pre){
        for(int i=head[u];~i;i=e[i].nxt){
            int v=e[i].to;
            if(v==pre)continue;
            dp2[v]=dp1[u]-dp1[v]+dp2[u]+(e[i].w?-1:1);      
            //dp2[v]=dp1[u]-dp1[v]-e[i].w+e[i^1].w+dp2[u];     
            //dp1[u]-dp1[u]-e[i].w+e[i^1].w表示v的父亲u的子树中,除v的子树的其它部分需要翻转的边数(从v向上走时),dp2[u]表示u向上的方向需要翻转的变数       
            dfs2(v,u);
        }
    }
    int main(){
        read(n);
        memset(head,-1,sizeof(head));
        REP(i,1,n-1){
            int u,v;read(u);read(v);
            add(u,v,0);add(v,u,1);
        }
        dfs1(1,-1);dfs2(1,-1);
        int ans=1e9;
        REP(i,1,n)ans=min(ans,dp1[i]+dp2[i]);
        cout<<ans<<endl;
        REP(i,1,n)if(ans==dp1[i]+dp2[i])cout<<i<<' ';
    }   
  • 相关阅读:
    Codeforces Round #594 (Div. 2) ABC题
    Codeforces Round #596 (Div. 2) ABCD题
    数据结构实验5——二叉树
    数据结构实验4——字符串匹配
    数据结构实验3——用栈求解算术表达式
    友链
    Codeforces Round #577 (Div. 2)
    Educational Codeforces Round 70 (Rated for Div. 2)
    Codeforces Round #578 (Div. 2)
    2020 Multi-University Training Contest 10(待补
  • 原文地址:https://www.cnblogs.com/00isok/p/10905702.html
Copyright © 2011-2022 走看看