The Key Sations_toj2189_割点

来源:互联网 发布:网络直播合同范本 编辑:程序博客网 时间:2024/06/01 08:18

Description

In the city named ACM, there aren’t any network stations by now, what’s a pity! So the government plans to establish a complete network, and decides to set up a team in charge of this project.

There are totally N districts. And the team plans to build one network station in each district. Also in order to make sure the communication of the city, there exists at least one path between any two stations, directly or indirectly. For the sack of safety, they hire some engineers working in stations so that if there are any problems they can fix them in no time. Considering the cost, they don’t want to hire enough engineers for each station, instead only for the key stations. The key station is the one that if it halts down, the network left isn’t connected any more. For example, in the graph given, station 1 is a key station, while the others are not.

So the problem is how to find all of the key stations in the city. The leader of the team, Jack, needs help! As a program expert, can you help him?

Input

The input consists of several blocks of lines. Each block describes one network. In the first line of each block there is the number of districts N ≤ 1000. Each of the next at most N lines contains the number of a station followed by the numbers of some stations to which there is a direct connection from this station.

These at most N lines completely describe the network, i.e., each direct connection of two stations in the network is contained at least in one row. All numbers in one line are separated by one space. Each block ends with a line containing just 0. The last block has only one line with N = 0.

Output

For each block, first output the number of the key stations m, then m ascending numbers are followed. The numbers are separated by exactly one blank.

Sample Input

5
1 5 2 4 3
4 3
5 2
0
5
1 2 3 4 5
3 2
4 3
5 2
0
0

Sample Output

1 1
0

Author: Kandy

Source: TOJ 2006 Weekly Contest 3

大意:

给定多个图求割点

吐槽:

没有什么好讲的了就来吐槽吧:

  • 输出坑爹,末尾不能多空格
  • 空行会被算wa
  • 没有割点也就是双联通图的时候输出0,后无空格

代码:

type  edge=record    opp,y,next:longint;    visit:boolean;  end;var  e:array[0..10000]of edge;  g,dfn,low,ls:array[0..2000]of longint;  ans:array[0..2000]of boolean;  n,m,maxE,t,num:longint;procedure add(x,y:longint);begin  inc(maxE);  e[maxE].y:=y;  e[maxE].opp:=maxE+1;  e[maxE].next:=ls[x];  ls[x]:=maxE;  inc(maxE);  e[maxE].y:=x;  e[maxE].opp:=maxE-1;  e[maxE].next:=ls[y];  ls[y]:=maxE;end;function min(x,y:longint):longint;begin  min:=x;  if y<x then  min:=y;end;procedure tarjan(x:longint);var  i:longint;begin  inc(t);  dfn[x]:=t;  low[x]:=t;  i:=ls[x];  while i>0 do  with e[i] do  begin    if not visit then    begin      visit:=true;      e[opp].visit:=true;      if dfn[y]=0 then      begin        if x=1 then inc(num);        tarjan(y);        low[x]:=min(low[y],low[x]);        if low[y]>=dfn[x] then        ans[x]:=true;      end      else      low[x]:=min( low[x],dfn[y]);    end;    i:=next;  end;end;procedure print;var  i:longint;begin  ans[1]:=false;  fillchar(g,sizeof(g),0);  if num>=2 then ans[1]:=true;  num:=0;  for i:=1 to n do  if ans[i] then  begin    inc(num);    g[num]:=i;  end;  write(num);  if num>0 then  begin    write(' ');    for i:=1 to num-1 do write(g[i],' ');    writeln(g[num]);  end  else  writeln;end;procedure main;var  x,y:longint;begin  read(n);  while n<>0 do  begin    fillchar(ans,sizeof(ans),false);    fillchar(dfn,sizeof(dfn),0);    fillchar(low,sizeof(low),0);    fillchar(ls,sizeof(ls),0);    fillchar(e,sizeof(e),0);    maxE:=0;    num:=0;    t:=0;    read(x);    while x<>0 do    begin      while not eoln do      begin        read(y);        add(x,y);      end;      read(x);    end;    tarjan(1);    print;    read(n);  end;end;begin  main;end.
0 0