Information(图论算法)

Description

It is a war between Country Alpha and Country Beta. Country Alpha gets following information about Country Beta:

Country Beta has n (2 <= n <= 100) cities numbered from 0 to n-1. Each city has a transmitter and a receiver. One city is able to transmit important information by its transmitter to another city. Meanwhile, if there's information transmitted to one city, it is able to receive the information by its receiver. Of course, it is OK that one city doesn't transmit any information to another city and that if no information transmitted to one city, the city receives no information. Thus, a quantity of cities are able to constitute a group. In a group, any city is able to transmit the information to any city in the group directly or indirectly. Of course, one city belongs to only one group.

Now, Country Alpha wants to demolish one city of Country Beta. Thus, Alpha will make the number of cities in the largest group as small as possible.

Input

Ther are multiple test cases (about 200 cases). There is a blank line between each case.

The first line of each case contains two positive integers, n and m (0 <= m <= 9900), in which m indicates the number of the path(es) of the information from one city to another. In each line of following m line(s), there are two positive integers, s, t, indicating that some information is from City s to City t. No same pair of (s,t).

Output

Output the least number of cities in a group, which is the largest group after Country Alpha's attack. By the way, a group must consist of at least two cities, that is, one city is not able to be considered as a group. If there is no group, output 0.

Sample Input
2 2 
0 1 
1 0
Sample Output
0
 
 
解题思路:其实这道题就是求强连通分量,可以用Kosaraju算法,首先利用深度优先搜索遍历原图,并按出栈顺序的先后顺序把点放进一个线性表里,这里可以每次取任意一个点出发DFS,如果还有点未被DFS到,那么继续任选未被遍历到的点出发DFS,然后将整个图转置,按照线性表中的出栈顺序,从后往前作为起点DFS。每次DFS到的就是一个强连通分量。
 
 
程序:
 
 
var
  a,b:array[0..100,0..100] of longint;
  f:array[1..100] of longint;
  v:array[0..100] of boolean;
  f1,n,s,m,x,y,i,j,max,min:longint;

procedure dfs1(x:longint);
  var
    i:longint;
  begin
    v[x]:=false;
    for i:=0 to n-1 do
      if (a[x,i]=1)and(v[i]) then dfs1(i);
    inc(f1);
    f[f1]:=x;
end;

procedure dfs2(x:longint);
  var
    i:longint;
  begin
    v[x]:=false;
    for i:=0 to n-1 do
      if (b[x,i]=1)and(v[i]) then dfs2(i);
    inc(s);
end;

begin
  while not eof do
    begin
      readln(n,m);
      fillchar(a,sizeof(a),0);
      fillchar(b,sizeof(b),0);
      for i:=1 to m do
        begin
          readln(x,y);
          a[x,y]:=1;
          b[y,x]:=1;
        end;
      min:=maxlongint;
      for i:=0 to n-1 do
        begin
          fillchar(v,sizeof(v),true);
          v[i]:=false;
          f1:=0;
          for j:=0 to n-1 do
            if v[j] then dfs1(j);
          fillchar(v,sizeof(v),true);
          v[i]:=false;
          max:=0;
          for j:=f1 downto 1 do
            if v[f[j]] then
              begin
                s:=0;
                dfs2(f[j]);
                if s>max then max:=s;
              end;
          if (max1) then min:=max;
          if max<2 then begin min:=0; break; end;
          if min=0 then break;
        end;
      if min=maxlongint then writeln(0) else writeln(min);
    end;
end.



版权属于: Chris
原文地址: http://blog.sina.com.cn/s/blog_83ac6af80102v3gn.html
转载时必须以链接形式注明原始出处及本声明。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值