zoukankan      html  css  js  c++  java
  • BZOJ1875:[SDOI2009]HH去散步

    Description

    HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

    Input

    第一行:五个整数N,M,t,A,B。其中N表示学校里的路口的个数,M表示学校里的 路的条数,t表示HH想要散步的距离,A表示散步的出发点,而B则表示散步的终点。 接下来M行,每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。数据保证Ai = Bi,但 不保证任意两个路口之间至多只有一条路相连接。 路口编号从0到N − 1。 同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 答案模45989。

    Output

    一行,表示答案。

    Sample Input

    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2

    Sample Output

    4

    HINT

    对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。 对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B

    题解:

    看数据范围就知道是矩阵快速幂了。

    因为不能立刻原路返回,所以不能单纯以位置作为矩阵的行。考虑将一条边拆为两个点,表示通过这条边从Ai走到Bi与从Bi走到Ai的情况(显然这两个状态不能互相到达)。以这些点加上起点作为矩阵的状态,然后在其之间构造转移方式,就得到了转移矩阵。求完快速幂后,把所有以终点作为到达点的状态方案数相加,即为答案。

    代码:

     1 const
     2   mo=45989;
     3 var
     4   i,j,k,l,n,m,t,s,e,ss,ee,cnt:longint;
     5   a:array[1..2,0..121,0..121]of longint;
     6   c:array[0..121,0..121]of longint;
     7   tt:array[0..121,1..2]of longint;
     8   ans:longint;
     9 procedure qq(z,x,y:longint);
    10 var i,j,k:longint;
    11 begin
    12   for i:=1 to cnt do
    13   for j:=1 to cnt do
    14   begin
    15     c[i,j]:=0;
    16     for k:=1 to cnt do c[i,j]:=(c[i,j]+a[x,i,k]*a[y,k,j])mod mo;
    17   end;
    18   for i:=1 to cnt do
    19   for j:=1 to cnt do a[z,i,j]:=c[i,j];
    20 end;
    21 procedure ksm(t:longint);
    22 begin
    23   while t>0 do
    24   begin
    25     if t mod 2=1 then qq(1,1,2);
    26     t:=t div 2; qq(2,2,2);
    27   end;
    28 end;
    29 begin
    30   readln(n,m,t,s,e); cnt:=1; inc(s); inc(e);
    31   for i:=1 to m do
    32   begin
    33     readln(j,k); inc(j); inc(k);
    34     inc(cnt); tt[cnt,1]:=j; tt[cnt,2]:=k;
    35     inc(cnt); tt[cnt,1]:=k; tt[cnt,2]:=j;
    36   end;
    37   for i:=2 to cnt do if tt[i,1]=s then a[2,1,i]:=1;
    38   for i:=2 to cnt do
    39   begin
    40     for j:=2 to cnt do
    41     if(tt[j,1]=tt[i,2])and(i xor 1<>j)then inc(a[2,i,j]);
    42   end;
    43   a[1,1,1]:=1;
    44   ksm(t);
    45   for i:=2 to cnt do if tt[i,2]=e then ans:=(ans+a[1,1,i])mod mo;
    46   writeln(ans);
    47 end.
    View Code
  • 相关阅读:
    动态创建DeepZoom
    MultiSheet Excel Output
    PL/SQL Developer设置技巧
    采购审批专题总结bob
    oracle dbms包和其他包的使用大全
    ARAuto Invoice question
    应收发票相关 脚本
    发运确认停靠站错误
    让R12直接从Form登录
    查找事物处理来源
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6298095.html
Copyright © 2011-2022 走看看