bzoj 1638 dfs

本文介绍了一种解决特定图论问题的方法,即求从所有入度为0的节点到编号为n的节点路径中,被经过最多次的边的经过次数。通过正反两次建立图模型,并使用深度优先搜索(DFS)算法来处理问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:n个点,m条有向边,从每个入度为0的点走到编号为n的点,求经过次数最多的边的经过次数

根据乘法原理易知:一条边(a,b)的经过次数=入度为0的点到a的路径条数*b到编号为n的路径条数

正反两次建图,分别跑两次dfs处理出即可

pascal同志记得开Q-(也可能是本蒟蒻写丑了)

{$Q-}
type
        rec=record
            a,b:longint;
end;

var
        n,m,ll          :longint;
        last,f,g        :array[0..5010] of longint;
        pre,other       :array[0..50010] of longint;
        i               :longint;
        ans             :longint;
        l               :array[0..50010] of rec;
procedure connect(x,y:longint);
begin
   inc(ll);
   pre[ll]:=last[x];
   last[x]:=ll;
   other[ll]:=y;
end;

procedure dfs1(x:longint);
var
        p,q:longint;
begin
   q:=last[x];
   if q=0 then
   begin
      f[x]:=1; exit;
   end;
   while (q<>0) do
   begin
      p:=other[q];
      if f[p]=0 then dfs1(p);
      inc(f[x],f[p]);
      q:=pre[q];
   end;
end;

procedure dfs2(x:longint);
var
        p,q:longint;
begin
   q:=last[x];
   if q=0 then
   begin
      g[x]:=1; exit;
   end;
   while (q<>0) do
   begin
      p:=other[q];
      if g[p]=0 then dfs2(p);
      inc(g[x],g[p]);
      q:=pre[q];
   end;
end;

begin
   read(n,m);
   for i:=1 to m do read(l[i].a,l[i].b);
   for i:=1 to m do connect(l[i].b,l[i].a);
   dfs1(n);
   ll:=0;
   for i:=1 to n do last[i]:=0;
   for i:=1 to m do connect(l[i].a,l[i].b);
   for i:=1 to n do if g[i]=0 then dfs2(i);
   ans:=0;
   for i:=1 to m do
     if (f[l[i].a]*g[l[i].b]>ans) then ans:=f[l[i].a]*g[l[i].b];
   writeln(ans);
end.
——by Eirlys


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值