The Key Sations_toj2189_割点

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值