poj 2186

Description

Everycow's dream is to become the most popular cow in the herd. In a herd of N (1<= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000)ordered pairs of the form (A, B) that tell you that cow A thinks that cow B ispopular. Since popularity is transitive, if A thinks B is popular and B thinksC is popular, then A will also think that C is 
popular, even if this is not explicitly specified by an ordered pair in theinput. Your task is to compute the number of cows that are considered popularby every other cow. 

Input

*Line 1: Two space-separated integers, N and M 

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B ispopular. 

Output

*Line 1: A single integer that is the number of cows who are considered popularby every other cow. 

Sample Input

3 3

1 2

2 1

2 3

Sample Output

1

Hint

Cow3 is the only cow of high popularity. 

 

题目大意:给定N头牛和M个关系(a,b)表示a认为b受欢迎,关系可以传递,问有多少头牛被其他牛都认为受欢迎。

 

分析:先跑一遍tarjan,把图G压缩成图G’,图中出度为0的点是最受欢迎的。果有多个出度为0的,那么无解,因为两个入度为0的互不认为受欢迎。


const

  MaxV=100000;

  MaxE=100000;

type

  arr=record

        next,x,y:longint;

      end;

var

  n,m,tot,dindex,bcnt:longint;

  ls,stack,low,dfn,belong,c,r:array[1..maxV] oflongint;

  g:array[1..MaxE] of arr;

  instack:array[1..maxv] of boolean;

procedureinit;

var

  i,s,m:longint;

begin

  readln(n,m);

  for i:=1 to m do

   begin

    with g[i] do

     begin

      readln(x,y);

      next:=ls[x];

      ls[x]:=i;

     end;

   end;

end;

 

functionmin(x,y:longint):longint;

 begin

  if x>y then exit(y)

         else exit(x);

 end;

 

functionmax(x,y:longint):longint;

 begin

  if x>y then exit(x)

         else exit(y);

 end;

 

proceduretarjan(i:longint);

varj,t:longint;

begin

 inc(dindex);

 low[i]:=dindex;

 dfn[i]:=dindex;

 inc(tot);

 stack[tot]:=i;

 t:=ls[i];

 instack[i]:=true;

 while t>0 do

  begin

   j:=g[t].y;

   if dfn[j]=0 then

    begin

     tarjan(j);

     low[i]:=min(low[i],low[j]);

    end

    else

     if instack[j] then

     low[i]:=min(low[i],dfn[j]);

    t:=g[t].next;

  end;

  if low[i]=dfn[i] then

   begin

    inc(bcnt);

    repeat

     j:=stack[tot];

     instack[j]:=false;

     dec(tot);

     belong[j]:=bcnt;

    until i=j;

   end;

end;

 

proceduresolve;

vari:longint;

begin

 dindex:=0;

 bcnt:=0;

 dindex:=0;

 fillchar(dfn,sizeof(dfn),0);

 for i:=1 to n do

  if dfn[i]=0 then

   begin

    tarjan(i);

   end;

end;

 

proceduremain;

 var j,i,k,ans:longint;

begin

 init;

 solve;

 ans:=0;

 for i:=1 to n do

  begin

   j:=ls[i];

   while j<>0do

    begin

     with g[j] do

      begin

       if belong[x]<>belong[y] then

        begin

         inc(c[belong[x]]);

         inc(r[belong[y]]);

        end;

       j:=next;

      end;

    end;

  end;

 j:=0;

 for i:=1 to bcnt do

  if c[i]=0 then

   begin

    if j=0 then j:=i

           else begin writeln(0); halt; end;

   end;

 if j=0 then begin writeln(0); halt; end;

 for i:=1 to n do

  if belong[i]=j then inc(ans);

  writeln(ans);

end;

 

begin

whilenot seekeof do

 begin

  main;

 end;

end.

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值