树形图计数(count)

算法:DFS

分析:题目是求从任意一个点开始到任意一个点结束,其中的路径长度为N,且中间不构成环的这样的情况有多少种。(有向图)

program count;

const
 maxn=8;

var
 s:array [0..maxn] of ansistring;
 f:array [0..maxn] of longint;{用f[i]表示是谁发现的i。}
 n,ans:longint;

procedure init;
var
 i:longint;
begin
 readln(n);
 for i:=1 to n do f[i]:=i;
 for i:=1 to n do readln(s[i]);
end;

function getf(x:longint):longint;{并查集,但是不能改变父亲节点。}
begin
 if x=f[x] then exit(x)
 else exit(getf(f[x]));
end;

procedure dfs(t,dep:longint);
var
 i:longint;
begin
 if dep=n+1 then
  begin
   inc(ans);
   exit;
  end;
 if t=dep then dfs(t,dep+1);{因为枚举以t为起点,因此不能有人发现t。}
 for i:=1 to n do
  begin
   if (i<>dep) and (s[i,dep]='1') and (getf(i)<>dep) then{不能自己发现自己,并且确认i不是被dep发现的,如果是的话再继续就形成了互相指的局面。}
    begin
     f[dep]:=i;{记录dep是i发现的。}
     dfs(t,dep+1);
     f[dep]:=dep;
    end;
  end;
end;

procedure main;
var
 i:longint;
begin
 for i:=1 to n do dfs(i,1);
end;

begin
 assign(input,'count.in'); reset(input);
 assign(output,'count.out'); rewrite(output);
 
 init;
 main;
 writeln(ans);
 
 close(input); close(output);
end.


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值