Codeforces Round #135 (Div. 2)D. Choosing Capital for Treeland

题意:n个点,n-1个边,有向的,问当以某个点为起点,到其他点的话要改变多少个边的方向

思路:题目给的边价值为0,反向的价值为1,f[i]表示该点到他的子节点需要改变的边,g[i]为到他上方需要改变的,跑2遍图

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e5+10;
 4 
 5 struct node{
 6     int to,next,val;
 7 }e[N*2];
 8 int head[N],tot;
 9 int f[N],g[N];
10 
11 void init(){
12     memset(head,-1,sizeof(head));
13     tot=0;
14 }
15 
16 void add(int u,int v,int w){
17     e[tot].to=v;e[tot].next=head[u];e[tot].val=w;
18     head[u]=tot++;
19 }
20 
21 void dfs1(int u,int fa){
22     for(int i=head[u];i!=-1;i=e[i].next){
23         int v=e[i].to,w=e[i].val;
24         if(v==fa) continue;
25        // cout<<u<<" "<<v<<" "<<w<<endl;
26         dfs1(v,u);
27         f[u]+=f[v]+w;
28     }
29 }
30 int Min=1e9+7;
31 void dfs2(int u,int fa){
32     Min=min(Min,f[u]+g[u]);
33     for(int i=head[u];i!=-1;i=e[i].next){
34         int v=e[i].to,w=e[i].val;
35         if(v==fa) continue;
36         g[v]=g[u]+f[u]-f[v]+(w==0?1:-1);
37         dfs2(v,u);
38     }
39 }
40 
41 int main(){
42     int n;
43     int x,y;
44     init();
45     scanf("%d",&n);
46     for(int i=1;i<n;i++){
47         scanf("%d%d",&x,&y);
48         add(x,y,0);
49         add(y,x,1);
50     }
51     dfs1(1,0);
52     dfs2(1,0);
53     cout<<Min<<endl;
54     for(int i=1;i<=n;i++){
55         if(f[i]+g[i]==Min)
56             printf("%d ",i);
57     }
58     printf("\n");
59 }

 

posted on 2017-07-13 21:31  hhhhx  阅读(153)  评论(0编辑  收藏  举报

导航