都城(树形DP)

题目描述:

 

题解:

正难则反,先求出让所有其它城市到达都城需反向几条边,再用总边数减去即可
 
f[i]表示以i为根的子树调整好需反向的边数
 
g[i]表示以i为都城需反向的边数
 
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000010;
struct Edge{
    int v,w,nxt;
}edge[N<<1];
int n,head[N],cnt,f[N],g[N];
void add_edge(int u,int v,int w){
    edge[++cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].nxt=head[u];
    head[u]=cnt;
}
void dfs1(int u,int fa){
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        int w=edge[i].w;
        if(v==fa) continue;
        f[u]+=w;
        dfs1(v,u);
        f[u]+=f[v];
    }
}
void dfs2(int u,int fa){
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        int w=edge[i].w;
        if(v==fa) continue;
        if(w==1) g[v]=g[u]-1;
        else g[v]=g[u]+1;
        dfs2(v,u);
    }
}
int main(){
    scanf("%d",&n);
    int u,v;
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        add_edge(u,v,1);
        add_edge(v,u,0);
    }
    dfs1(1,0);
    g[1]=f[1];
    dfs2(1,0);
    for(int i=1;i<=n;i++) printf("%d\n",n-1-g[i]);
    return 0;
}

 

posted @ 2019-08-19 16:21  Mistletoes  阅读(109)  评论(0编辑  收藏  举报