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.