您的位置:首页 > 运维架构

poj 2186 Popular Cows 强连通分量

2016-06-04 10:27 405 查看
题目大意

  n头奶牛,给出若干个欢迎关系a b,表示a欢迎b,欢迎关系是单向的,但是是可以传递的。另外每个奶牛都是欢迎他自己的。求出被所有的奶牛欢迎的奶牛的数目

 

分析

  先跑一遍taijian算法。那么出度为0的强连通分量代表的就是受其他奶牛欢迎的,但是如果出度为0的强连通分量的个数大于1那么则无解。因为将至少有两个分量里的奶牛互相不喜欢(因为他们的出度为0,不连接其他点,就不喜欢另一个同样情况的强连通分量)。所以我们的算法就是如果出度为0的强连通分量的个数是1.那么我们算出这里面点的个数就是最后的答案。

 

代码

const
maxe=500000;
maxv=20000;

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,m);
k:=0;
ans:=0;
for i:=1 to m do
begin
readln(j,k);
with g[i] do
begin
x:=j;
y:=k;
next:=ls[x];
ls[x]:=i;
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;
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=k+1;
if k<>1
then
begin
write(0);
halt;
end;
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=i;
j:=0;
for i:=1 to n do
if a[i]=k then j:=j+1;
write(j);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: