POJ3180 The Cow Prom Tarjan 链接表 pascal 解题报告

由于手残的问题,之前先把第三题给发了,这是我的Tarjan第二题

题目大意:题目的原意懒得翻译了,大概就是说有N个牛,围在一水池边,它们用绳子互相绑着(有方向的)。如果绳子的方向一致,它们就能顺时针转,问有多少组牛可以跳舞

思路:还是先画图,画完之后很快可以明白又是一道水题:读入n,m(2<=n<=10000,2<=m<=50000),其中有n个点,m条边,下面每行给出一条边的信息,求出强连通块内点数大于等于2的块的数量(也就意味着不用存储,遍历一次统计一下就好了)。

没啥需要注意的,懒的话直接把2186的代码改一下直接可以过,但是初学还是多打一次增加以下熟练度,没有1A真觉得对不起自己和老师

type
  rec=record
        next,t:longint;
      end;
var
  f,v:array[1..10010] of boolean;
  edge:array[1..50010] of rec;
  head,low,dfn,stack:array[1..10010] of longint;
  n,m,x,y,ans,deep,top,t,tmp,sum,i:longint;
  function min(a,b:integer):longint;
  begin
    if a<b then exit(a) else exit(b);
  end;
  procedure pop(k:longint);
  begin
    ans:=0;                         //统计点数
    while stack[top+1]<>k do
    begin
      inc(ans);
      f[stack[top]]:=false;
      dec(top);
    end;
    if ans>=2 then inc(sum);       //都说了不用存的
  end;
  procedure dfs(k:longint);
  var
    tmp:longint;
  begin
    inc(deep);
    low[k]:=deep; dfn[k]:=deep; v[k]:=true;
    inc(top);
    stack[top]:=k; f[k]:=true;
    tmp:=head[k];
    while tmp<>-1 do
    begin
      if v[edge[tmp].t]=false then
      begin
        dfs(edge[tmp].t);
        low[k]:=min(low[k],low[edge[tmp].t]);
      end
      else
        if f[edge[tmp].t] then low[k]:=min(low[k],dfn[edge[tmp].t]);
      tmp:=edge[tmp].next;
    end;
    if dfn[k]=low[k] then pop(k);
  end;
begin
  readln(n,m);
  for i:=1 to n do head[i]:=-1; fillchar(edge,sizeof(edge),0);     //初始化
  for i:=1 to m do
  begin
    readln(x,y);
    edge[i].t:=y;
    edge[i].next:=head[x];
    head[x]:=i;
  end;
  fillchar(v,sizeof(v),false); fillchar(f,sizeof(f),false);
  for i:=1 to n do
    if v[i]=false then dfs(i);                                      //tarjan
  writeln(sum);  
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值