zoukankan      html  css  js  c++  java
  • SCOI2009 迷路

    有向图有 N 个节点,从节点 0 出发,必须恰好在 T 时刻到达节点 N-1。 现在给出该有向图,总共有多少种不同的路径

    注意:不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。

    用矩阵乘法把n个01邻接矩阵(连通性矩阵,a[i,j]=1表示 i 到 j 有一条有向边相连),则a[i,j]就表示走n步后从i到j的不同的路的条数。由于题目中边有权,而权值只是1..9,所以可以把每个点拆成9个点,即第i个点变成第9*(i-1)+1到第9*(i-1)+9个点,把这n个点各自拆出来的9个点串连

    即a[9*(i-1)+j,9*(i-1)+j+1]:=1(1<=j<=8),读入邻接矩阵时i到j权值是k,就从9*(i-1)+k往9*(j-1)+1上连一条边,用矩阵乘法快速幂在logN的时间内求出a^N,则a[1,9*(n-1)+1]为解。

    这个程序写的有些烂,数据在1.0x s出解,自己看着优化下常数,写递归快速幂还爆栈。。

    改改改。。。。。。

    终于发现问题了,数组开成integer就0.1出解了,没想到int64那么慢。

    View Code
     1 {$inline on}
     2 program road(input,output);
     3 type
     4    numbertype=array[0..91,0..91] of integer;//就这里,写成int64过不了
     5 var 
     6    map        : array[0..11,0..11] of integer;
     7    power    : array[0..30] of numbertype;
     8    v        : array[0..30] of boolean;
     9    f,answer,tmp    : numbertype;
    10    n,t        : longint;
    11 procedure init; inline;
    12 var
    13    i,j : longint;
    14    ch  : char;
    15 begin
    16    readln(n,t);
    17    for i:=1 to n do
    18    begin
    19       for j:=1 to n do
    20       begin
    21      read(ch);
    22      map[i,j]:=ord(ch)-48;
    23       end;
    24       readln;
    25    end;
    26    fillchar(f,sizeof(f),0);
    27    for i:=1 to n do
    28       for j:=1 to 8 do
    29      f[9*(i-1)+j,9*(i-1)+j+1]:=1;
    30    for i:=1 to n do
    31       for j:=1 to n do
    32      if map[i,j]>0 then
    33         f[9*(i-1)+map[i,j],9*(j-1)+1]:=1;
    34 end; { init }
    35 procedure main(y:longint ); inline;
    36 var
    37    i,tt,j,k,l,s    : longint;
    38 begin
    39    for i:=1 to 9*n do
    40       for j:=1 to 9*n do
    41      power[1][i,j]:=f[i,j];
    42    s:=y;
    43    tt:=trunc(ln(y)/ln(2))+1;
    44    fillchar(v,sizeof(v),false);
    45    dec(s);
    46    answer:=f;
    47    for i:=1 to tt do
    48       if (s>>(i-1))and 1=1 then
    49      v[i]:=true;
    50    for i:=2 to tt do
    51    begin
    52       fillchar(power[i],sizeof(power[i]),0);
    53       for j:=1 to 9*n do
    54      for k:=1 to 9*n do
    55         for l:=1 to 9*n do
    56            power[i][j,l]:=(power[i][j,l]+power[i-1][j,k]*power[i-1][k,l])mod 
    57 
    58 2009;
    59    end;
    60    for i:=1 to tt do
    61       if v[i] then
    62       begin
    63      fillchar(tmp,sizeof(tmp),0);
    64      for j:=1 to 9*n do
    65         for k:=1 to 9*n do
    66            for l:=1 to 9*n do
    67           tmp[j,l]:=(tmp[j,l]+answer[j,k]*power[i][k,l])mod 2009;
    68      for j:=1 to 9*n do
    69         for k:=1 to 9*n do
    70            answer[j,k]:=tmp[j,k];
    71       end;
    72 end; { main }
    73 begin
    74    assign(input,'road.in');reset(input);
    75    assign(output,'road.out');rewrite(output);
    76    init;
    77    main(t);
    78    writeln(answer[1,9*(n-1)+1]);
    79    close(input);
    80    close(output);
    81 end.
  • 相关阅读:
    kali国内更新源
    nmap教程(下)
    nmap教程(上)
    apt-get常用命令
    linux如何制作程序桌面快捷方式
    linux怎么把英文版火狐浏览器改成中文
    百度地图demo
    普元云计算-一起来DIY一个人工智能实验室吧
    普元云计算-拥抱人工智能,从机器学习开始
    普元云计算-Java开发者的PaaS指南
  • 原文地址:https://www.cnblogs.com/neverforget/p/2454112.html
Copyright © 2011-2022 走看看