A country, there are N cities, numbered 1~n, there are n-1 to the edge
If we don't consider the direction of the edges, these n cities just form a tree.
Now the king is going to choose one of these n cities as the capital.
Request: From the capital can be reached in any city of this country (side is a direction)
So a city as the capital, there may be a number of sides need to change direction
Now ask, choose which cities as the capital, need to change the direction of the least side.
Output minimum number of edges that need to change direction
The output can be used as the capital's number
Tree-shaped DP
First assume the City 1 as the capital
Make tree (i) a subtree that is rooted in I
Dp[i] Indicates the number of edges that need to be changed if I is the capital of the tree (i)
First time DFS, find the DP array
Ans[i] Indicates the number of sides to change (note the difference between the meaning of the DP array) If I is the capital of the whole tree.
Obvious: ans[1]=dp[1]
Obviously there are:
In a directed tree, if the capital is U, now we want to make U's son node v the capital, only need to change the direction of 1 sides
Suppose node U is the parent node of Node V, e= (u,v), Ans[u] Known
If the direction of E is pointing to V, then: ans[v]=ans[u]+1
otherwise: ans[v]=ans[u]-1
So the second time Dfs, recursion out the ANS array
Next, find Min=min (Ans[i]) and output min
Outputs all of the I that make the ans[i]==min
1#include <cstdio>2#include <cstring>3 4 using namespacestd;5 6 Const intmaxn=200000+5;7 8 structEdge9 {Ten intTo,next; One BOOLFlag; A }; -Edge edge[maxn<<1]; - intHEAD[MAXN]; the inttot; - intANS[MAXN]; - intDP[MAXN]; - intPRINT[MAXN]; + - voidInit () + { Amemset (head,-1,sizeofhead); attot=0; -Memset (DP,0,sizeofDP); - } - - voidAddedge (intUintVBOOLflag) - { inedge[tot].to=v; -edge[tot].flag=Flag; toedge[tot].next=Head[u]; +head[u]=tot++; - } the * voidDfs0 (int,int ); $ voidDFS1 (int,int );Panax Notoginseng - intMain () the { + intN; A init (); the BOOLCnt=true; +scanf"%d",&n); - for(intI=1; i<n;i++) $ { $ intu,v; -scanf"%d%d",&u,&v); - Addedge (u,v,cnt); theAddedge (v,u,!CNT); - }WuyiDfs0 (1,-1); theans[1]=dp[1]; -DFS1 (1,-1); Wu - intmin=ans[1]; About for(intI=2; i<=n;i++) $ { - if(ans[i]<min) -min=Ans[i]; - } Atot=1; + for(intI=1; i<=n;i++) the { - if(ans[i]==min) $ { theprint[tot++]=i; the } the } the -printf"%d\n", min); in for(intI=1; i<tot-1; i++) the { theprintf"%d", Print[i]); About } theprintf"%d\n", print[tot-1]); the the return 0; + } - the voidDfs0 (intUintpre)Bayi { the for(intI=head[u];~i;i=edge[i].next) the { - intv=edge[i].to; - BOOLflag=Edge[i].flag; the if(v==pre) the Continue; the Dfs0 (v,u); the if(flag) -dp[u]+=Dp[v]; the Else thedp[u]+= (dp[v]+1); the }94 return ; the } the the voidDFS1 (intUintpre)98 { About for(intI=head[u];~i;i=edge[i].next) - {101 intv=edge[i].to;102 intflag=Edge[i].flag;103 if(v==pre)104 Continue; the if(flag)106ans[v]=ans[u]+1;107 Else108ans[v]=ans[u]-1;109 DFS1 (v,u); the }111 return ; the}
View Code
CF 219D Choosing capital for Treeland tree DP Good question