都城(树形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; }