tarjan题目(1)Victoria的舞会2

来源:互联网 发布:取消淘宝账号实名认证 编辑:程序博客网 时间:2024/06/10 03:14

【题目描述】:

Victoria是一位颇有成就的艺术家,他因油画作品《我爱北京天安门》闻名于世界。现在,他为了报答帮助他的同行们,准备开一个舞会。

  Victoria准备邀请n个已经确定的人,可是问题来了:
  这n个人每一个人都有一个小花名册,名册里面写着他所愿意交流的人的名字。比如说在A的人名单里写了B,那么表示A愿意与B交流;但是B的名单里不见的有A,也就是说B不见的想与A交流。但是如果A愿意与B交流,B愿意与C交流,那么A一定愿意与C交流。也就是说交流有传递性。
  Victoria觉得需要将这n个人分为m组,要求每一组的任何一人都愿意与组内其他人交流。并求出一种方案以确定m的最小值是多少。

  注意:自己的名单里面不会有自己的名字。

【输入格式】:

第一行一个数n。接下来n行,每i+1行表示编号为i的人的小花名册名单,名单以0结束。1<=n<=200。

【输出格式】;

一个数,m。

【输入样例】:

18
0
18 0
0
0
11 0
0
0
0
0
0
5 0
0
0
0
0
0
0
2 0

【输出样例】:

16


分析:题意比较清楚,算出有向图的强连通分量有多少就可以了。tarjan算法直接裸过。

代码:

var
  a:array [1..1000,1..1000] of longint;
  low,dfn,c:array [1..1000] of longint;
  v,f,ff:array [1..1000] of boolean;
  i,j,m,n,x,y,d,ans:longint;


function min(x,y:longint):longint;
begin
  if x>y then
  exit(y);
  exit(x);
end;


procedure tarjan(x:longint);
var
  i:longint;
begin
  inc(d);
  low[x]:=d;
  dfn[x]:=d;
  f[x]:=true;
  for i:=1 to c[x] do
  begin
    if not v[a[x,i]] then
    begin
      v[a[x,i]]:=true;
      tarjan(a[x,i]);
      low[x]:=min(low[x],low[a[x,i]]);
    end else
    begin
      if f[a[x,i]] then
      low[x]:=min(low[x],dfn[a[x,i]]);
    end;
  end;
  if dfn[x]=low[x] then
  inc(ans);
end;


begin
  readln(n);
  for i:=1 to n do
  begin
    read(x);
    while x<>0 do
    begin
      inc(c[i]);
      a[i,c[i]]:=x;
      read(x);
    end;
  end;
  for i:=1 to n do
  if not v[i] then
  begin
    v[i]:=true;
    tarjan(i);
  end;
  writeln(ans);
end.

0 0
原创粉丝点击