zoukankan      html  css  js  c++  java
  • BZOJ1297: [SCOI2009]迷路 矩阵乘法

    如果边权都是1,那么直接对当前的邻接矩阵进行T次自乘,答案就是D[1][n]了。

    证明:当进行1次自乘时,(D^{1}_{i,j})显然代表从i到j的长度为1的路径条数。假设(D^{k}_{i,j})表示从i到j长度为k的路径条数,(D^{k+1}_{i,j})表示从i到j长度为k+1的路径条数,那么(D^{k + 1} = D^{k} imes D)的(D^{k + 1}_{i, j} = sum_{k = 1}^{n}(D^{k}_{i,k} imes D^{1}_{k,j})),易知假设成立。得证。

    那么对于这道题有什么帮助呢?发现路径长度最长为9,我们可以把每个点拆成至多9个点连成一个链,对于边权为t的边{i, j}连上{I, J - t + 1},这样每条边的权值都是1,可以做了。

      1 //{HEADS
      2 #define FILE_IN_OUT
      3 #define debug
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <cmath>
      8 #include <ctime>
      9 #include <algorithm>
     10 #include <iostream>
     11 #include <fstream>
     12 #include <vector>
     13 #include <stack>
     14 #include <queue>
     15 #include <deque>
     16 #include <map>
     17 #include <set>
     18 #include <bitset>
     19 #include <complex>
     20 #include <string>
     21 #define REP(i, j) for (int i = 1; i <= j; ++i)
     22 #define REPI(i, j, k) for (int i = j; i <= k; ++i)
     23 #define REPD(i, j) for (int i = j; 0 < i; --i)
     24 #define STLR(i, con) for (int i = 0, sz = con.size(); i < sz; ++i)
     25 #define STLRD(i, con) for (int i = con.size() - 1; 0 <= i; --i)
     26 #define CLR(s) memset(s, 0, sizeof s)
     27 #define SET(s, v) memset(s, v, sizeof s)
     28 #define mp make_pair
     29 #define pb push_back
     30 #define PL(k, n) for (int i = 1; i <= n; ++i) { cout << k[i] << ' '; } cout << endl
     31 #define PS(k) STLR(i, k) { cout << k[i] << ' '; } cout << endl
     32 using namespace std;
     33 #ifdef debug
     34 #ifndef ONLINE_JUDGE
     35     const int OUT_PUT_DEBUG_INFO = 1;
     36 #endif
     37 #endif
     38 #ifdef ONLINE_JUDGE
     39     const int OUT_PUT_DEBUG_INFO = 0;
     40 #endif
     41 #define DG if(OUT_PUT_DEBUG_INFO)
     42 void FILE_INIT(string FILE_NAME) {
     43 #ifdef FILE_IN_OUT
     44 #ifndef ONLINE_JUDGE 
     45     freopen((FILE_NAME + ".in").c_str(), "r", stdin);
     46     freopen((FILE_NAME + ".out").c_str(), "w", stdout);
     47 
     48 #endif
     49 #endif
     50 }
     51 typedef long long LL;
     52 typedef double DB;
     53 typedef pair<int, int> i_pair;
     54 const int INF = 0x3f3f3f3f;
     55 //}
     56 /*{ 获取字符*/
     57 char gchar() {
     58     char ret = getchar();
     59     for(; ret == '
    ' || ret == '
    ' || ret == ' '; ret = getchar());
     60     return ret;
     61 }
     62 /*}*/
     63 const int maxn = 10 * 10;
     64 const int mod = 2009;
     65 int n, T, S;
     66 
     67 struct Matrix {
     68     int d[maxn][maxn];
     69     Matrix(int t = 0) {
     70         if(t == 1) {
     71             REP(i, S) {
     72                 d[i][i] = 1;
     73             }
     74         } else {
     75             CLR(d);
     76         }
     77     }
     78 }G, ans;
     79 
     80 Matrix operator * (const Matrix & a, const Matrix &b) {
     81     Matrix ret;
     82     REP(i, S) {
     83         REP(j, S) {
     84             REP(k, S) {
     85                 ret.d[i][j] = (ret.d[i][j] + a.d[i][k] * b.d[k][j] % mod) % mod;
     86             }
     87         }
     88     }
     89     return ret;
     90 }
     91 
     92 int main() {
     93     FILE_INIT("BZOJ1297");
     94 
     95     scanf("%d %d", &n, &T);
     96     S = n * 9;
     97     REP(i, n) {
     98         REP(j, n) {
     99             int t = gchar() - '0';
    100             if(t != 0) {
    101                 G.d[i * 9][j * 9 - t + 1] = 1;
    102                 for(int k = j * 9 - t + 2; k <= j * 9; ++k) {
    103                     G.d[k - 1][k] = 1;
    104                 }
    105             }
    106         }
    107     }
    108     /*
    109     REP(i, S) {
    110         REP(j, S) {
    111             printf("%d ", G.d[i][j]);
    112         }
    113         puts("");
    114     }
    115     */
    116     for(ans = 1; T; T >>= 1, G = G * G) {
    117         if(T & 1) {
    118             ans = ans * G;
    119         }
    120     }
    121     printf("%d
    ", ans.d[9][S]);
    122 
    123 
    124     return 0;
    125 }
    View Code
  • 相关阅读:
    一些总结与思考(聊聊最近,希望对大家有所帮助)
    操作符、语句、函数——Javascript高级程序设计
    Javascript高级程序设计——语法、关键字、保留字、变量、数据类型
    Javascript高级程序设计——Javascript简史+使用Javascript
    Angular.js!(附:聊聊非原生框架项目)
    JS事件绑定深入
    Javascript事件绑定及深入
    实现API管理系统的几个重要关键词
    实现API优先设计的重要性和实现方式
    对API进行版本控制的重要性和实现方式
  • 原文地址:https://www.cnblogs.com/hzf-sbit/p/3878490.html
Copyright © 2011-2022 走看看