2001. 【2015.8.6普及组模拟赛】Candy选首都(treeland) 题解

来源:互联网 发布:创建文件夹没权限linux 编辑:程序博客网 时间:2024/05/18 21:40
  Treeland是一个有n个城市组成的国家,其中一些城市之间有单向边连通。在这个国家中一共有n-1条路。我们知道,如果我们不考虑路的方向,那么我可以从任意城市到达任意城市。
      最近,Treeland的总理Candy为了发展经济,想要从这n个城市中选择一个作为Treeland的首都,首都必须要能到达其他任意城市,这使得有些道路必须反向,付出的代价即需要反向的道路条数。
      Candy想要选择一个城市作为首都,使得付出的代价最小。可能有多个城市满足条件,按编号从小到大输出。  

输入

第一行,一个整数n,表示城市个数接下来n-1行,每行两个整数x、y,表示城市x到城市y之间有一条单向路径

输出

第一行,一个整数k,花费的最小代价。第二行若干个整数,中间用空格隔开,表示满足条件的城市编号。行末没有多余的空格。

样例输入

Sample Input1:32 12 3Sample Input2:41 42 43 4 

样例输出

Sample Output1:02Sample Output2:21 2 3

代码如下
type  jl=record       x,y,next:longint;       end;var  x,y,n,i,tot,ans,min:longint;  f,sum,h:array[1..200000]of longint;  bz:array[1..200000]of boolean;  e:array[1..500000]of jl;procedure dfs2(x:longint);  var    p:longint;  begin    bz[x]:=true;sum[x]:=min;    if min<ans then ans:=min;    p:=h[x];    while p<>0 do     begin      if not bz[e[p].x]then       if e[p].y=x then         begin  dec(min);  dfs2(e[p].x);  inc(min); end        else begin  inc(min);  dfs2(e[p].x);  dec(min); end;      p:=e[p].next;     end;  end;procedure dfs1(x:longint);  var    p:longint;  begin    bz[x]:=true;    p:=h[x];    while p<>0 do     begin      if not bz[e[p].x]then       begin        dfs1(e[p].x);        f[x]:=f[x]+f[e[p].x];        if e[p].y=x then inc(f[x]);       end;      p:=e[p].next;     end;  end;procedure insert(x,y,z:longint);  begin   inc(tot);   e[tot].x:=y;   e[tot].y:=z;   e[tot].next:=h[x];   h[x]:=tot;  end;begin  assign(input,'treeland.in');reset(input);assign(output,'treeland.out');rewrite(output);  read(n);  for i:=2 to n do   begin    read(x,y);    insert(x,y,y);    insert(y,x,y);   end;  dfs1(1);  ans:=maxlongint;  fillchar(bz,sizeof(bz),false);  min:=f[1];  dfs2(1);  writeln(ans);  for i:=1 to n do if sum[i]=ans then write(i,' ');  close(input);close(output);end.
因为有N个点,N-1条边,所以这其实是一棵树。
先用暴力求出点1为首都所需的代价,然后用它来更新其他的点。
举个栗子:
用点1维护点2,如果
0 0