poj 1236 Network of Schools 强连通分量

来源:互联网 发布:提升应变能力 知乎 编辑:程序博客网 时间:2024/06/01 10:01

题目大意

  N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,

问题

1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。

2,至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

 

分析

  先跑一遍taijian算法。然后把一个强连通分量当做一个点,求入度为0的点的个数,就是问题一的答案(因为只有入度为0的强连通分量要分一套软件)。再求出度为0的点的个数,

第二个问题就输出max(入度0,出度0),因为要把这些点连在一起。

 

代码

const  maxe=50000;  maxv=1000;type  rec=record        x,y,w,next:longint;      end;var  n,m:longint;  g:array[1..maxe] of rec;  ls:array[1..maxv] of longint;  v,a,ru,cu:array[1..maxv] of longint;  low,dfn:array[1..maxv] of longint;  zan:array[1..maxv] of longint;  tot,ans,tot1:longint;  i,j,k:longint;procedure dfs(r:longint);var  i,j,k:longint;begin  tot:=tot+1;  zan[tot]:=r;  v[r]:=1;  tot1:=tot1+1;  low[r]:=tot1;  dfn[r]:=tot1;  i:=ls[r];  while i<>0 do    with g[i] do      begin        if dfn[y]=0          then            begin              dfs(y);              if low[r]>low[y] then low[r]:=low[y];            end          else            if (low[r]>dfn[y]) and (v[y]=1)              then low[r]:=dfn[y];        i:=next;      end;  if low[r]=dfn[r]    then      begin        ans:=ans+1;        repeat          j:=zan[tot];          tot:=tot-1;          a[j]:=ans;          v[j]:=0;        until j=r;      end;end;begin  readln(n);  k:=0;  ans:=0;  for i:=1 to n do    begin      read(j);      while j<>0 do        begin          k:=k+1;          with g[k] do            begin              x:=i;              y:=j;              next:=ls[i];              ls[i]:=k;            end;          read(j);        end;    end;  for i:=1 to n do    if a[i]=0      then        dfs(i);  for i:=1 to n do    begin      j:=ls[i];      while j<>0 do        with g[j] do          begin            if a[x]<>a[y]              then                begin                  cu[a[x]]:=cu[a[x]]+1;                  ru[a[y]]:=ru[a[y]]+1;                end;            j:=next;          end;    end;  j:=0;  for i:=1 to ans do    if ru[i]=0 then j:=j+1;  writeln(j);  k:=0;  for i:=1 to ans do    if cu[i]=0 then k:=k+1;  if ans=1 then    begin      write(0);      halt;    end;  if k>j then write(k)         else write(j);end.



1 0