• Codeforces 219D Choosing Capital for Treeland(树形DP)


    题目是给一张边有向的树形图。要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向。问可以选哪几个点作为首都,使它们所需反转边的数量最少。

    这题挺好想的,因为做过HDU2196

    • 首先就不妨设正向边权值为0,反向边权值为1,那样就是各个点出发到其他点经过边所需的最少权值和。
    • 然后对于每个点,分两个部分考虑:以这个点为根的子树这个点往上走的部分
      1. dp[0][u]表示以u点作为首都且以u点为根的子树部分所需反转边的数量,容易知道就等于子树内边权和
      2. dp[1][u]表示以u点作为首都且u点向上部分所需反转边的数量,画下图就知道怎么转移了:dp[1][v] = ( dp[0][u]-dp[0][v]-weight(u,v) ) + dp[1][u] + weight(v,u) (v是u的孩子)
    • 这样最后对于每个点u,它的答案就是这两部分之和了,即dp[0][u]+dp[1][u]。

    感觉又学到一种树形DP的新姿势:分别考虑点往下的子树和点往上的父亲部分。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define INF (1<<30)
     6 #define MAXN 222222
     7 struct Edge{
     8     int u,v,w,next;
     9 }edge[MAXN<<1];
    10 int NE,head[MAXN];
    11 void addEdge(int u,int v,int w){
    12     edge[NE].u=u; edge[NE].v=v; edge[NE].w=w;
    13     edge[NE].next=head[u]; head[u]=NE++;
    14 }
    15 int d[2][MAXN];
    16 void dfs0(int u,int fa){
    17     for(int i=head[u]; i!=-1; i=edge[i].next){
    18         int v=edge[i].v;
    19         if(v==fa) continue;
    20         dfs0(v,u);
    21         d[0][u]+=d[0][v]+edge[i].w;
    22     }
    23 }
    24 void dfs1(int u,int fa){
    25     for(int i=head[u]; i!=-1; i=edge[i].next){
    26         int v=edge[i].v;
    27         if(v==fa) continue;
    28         d[1][v]=d[0][u]-d[0][v]-edge[i].w+d[1][u]+edge[i^1].w;
    29         dfs1(v,u);
    30     }
    31 }
    32 int main(){
    33     memset(head,-1,sizeof(head));
    34     int n,a,b;
    35     scanf("%d",&n);
    36     for(int i=1; i<n; ++i){
    37         scanf("%d%d",&a,&b);
    38         addEdge(a,b,0); addEdge(b,a,1);
    39     }
    40     dfs0(1,1);
    41     dfs1(1,1);
    42     int res=INF;
    43     for(int i=1; i<=n; ++i) res=min(res,d[0][i]+d[1][i]);
    44     printf("%d
    ",res);
    45     for(int i=1; i<=n; ++i){
    46         if(res==d[0][i]+d[1][i]){
    47             printf("%d ",i);
    48         }
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    iOS开发拓展篇—音频处理(音乐播放器5)
    在Unity中接入Xbox360手柄
    POJ 2531 Network Saboteur(DFS)
    小塔1024实现
    Cocos2dx--开发环境搭建
    2.7 视图合并
    Cocos2d-X开发中国象棋《四》设计游戏场景
    libsqlite3.dylib与libsqlite3.0.dylib的差别
    AsyncTask
    开发,从需求出发 &#183; 之二 造飞机的工厂
  • 原文地址:https://www.cnblogs.com/WABoss/p/5267944.html
Copyright © 2020-2023  润新知