zoukankan      html  css  js  c++  java
  • HDU2254_奥运_矩阵_图论应用

    这道题目把矩阵跟图论完美地结合在了一起,矩阵与图论,本来就是难舍难分。能一下子想到相关知识,还是比较有难度

    要看多点书嘞。

    /*
    *题目大意:
    *        他知道中国有很多的名胜古迹,他知道自己在t1 到 t2天内不可能把所有的
    *        地方都玩遍,所以他决定指定两个地方v1,v2,如果参赛员能计算出在t1到t2天
    *        (包括t1,t2)内从v1到v2共有多少种走法(每条道路走需要花一天的时间,且不
    *        能在某个城市停留,且t1=0时的走法数为0),那么他就会获得相应数量的金牌,
    *        城市的总数<=30,两个城市间可以有多条道路,每条都视为是不同的。
    *解题思路:
    *        以每两个点之间路径的数量建立邻接矩阵A,然后邻接矩阵的l次幂就代表两个点之间
    *        路径长度为l的数量。而当算A^1 + A^2 + A^3 + A^4 + …… + A^l时,就代表邻接矩阵
    *        中任意两点的长度为1~l的数量。来到这里,就足够解决该题了。
    */
    View Code
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <map>
      5 
      6 #define MAX_DIMENSION 31 
      7 
      8 using namespace std;
      9 
     10 typedef int MATRIX_TYPE;
     11 typedef int MAX_INT_TYPE; 
     12 typedef MATRIX_TYPE Matrix[MAX_DIMENSION][MAX_DIMENSION];
     13 int ndim=MAX_DIMENSION;
     14 int mod = 2008;
     15 
     16 void m_zero(Matrix  x)
     17 {
     18     memset(x, 0, sizeof(MATRIX_TYPE)*MAX_DIMENSION*MAX_DIMENSION);
     19 }
     20 
     21 void m_one(Matrix  x)
     22 {
     23     int i;
     24     m_zero(x);
     25     for(i=0;i<ndim;++i)x[i][i]=1;
     26 }
     27 
     28 void m_copy(Matrix  src,Matrix  dest)
     29 {
     30     memcpy(dest,src, sizeof(MATRIX_TYPE)*MAX_DIMENSION*MAX_DIMENSION);
     31 }
     32 
     33 //z=x+y;
     34 void m_add(Matrix  x,Matrix  y,Matrix  z)
     35 {
     36     int i,j;
     37     for(i=0;i<ndim;i++)
     38         for(j=0;j<ndim;j++)
     39             if(mod<=1)z[i][j]=x[i][j]+y[i][j];
     40             else z[i][j]=(x[i][j]+(MAX_INT_TYPE)y[i][j])%mod;//module
     41 }
     42 
     43 
     44 //c=a*b
     45 void m_multiple(Matrix  a,Matrix b,Matrix c)
     46 {
     47     int i,j,k;
     48     MAX_INT_TYPE t;
     49 
     50     for(i=0;i<ndim;i++)
     51         for(j=0;j<ndim;j++)
     52         {
     53             t=0;
     54             if(mod<=1)
     55                 for(k=0;k<ndim;k++) t+=a[i][k]*b[k][j];//module
     56             else
     57                 for(k=0;k<ndim;k++){
     58                     t+=(a[i][k]*(MAX_INT_TYPE)b[k][j])%mod;
     59                     t%=mod;
     60                 }//module
     61             c[i][j]=t;
     62         }
     63 }
     64 
     65 //根据已经算出来的x^1 x^2 x^4 ...去求矩阵的幂y=x^n
     66 void m_pow_with_saved(Matrix  x_p[],unsigned int n, Matrix y)
     67 {
     68     Matrix temp;
     69     m_one(y);
     70     for(int k=1;n;++k,n>>=1)
     71     {
     72         if ((n & 1) != 0)
     73         {
     74             m_multiple(x_p[k],y,temp);
     75             m_copy(temp,y);
     76         }
     77     }
     78 }
     79 
     80 //计算根据已经算出来的x^1 x^2 x^4 ...去求矩阵的幂和y=sum(x^n)
     81 void m_pow_sum1(Matrix  x_p[],unsigned int n, Matrix y)
     82 {
     83     m_zero(y);
     84     if(n==0)return;
     85     if(n==1) m_copy(x_p[1],y);
     86     else
     87     {
     88         Matrix temp;
     89         //calculate x^1+...+^(n/2)
     90         m_pow_sum1(x_p,n>>1,temp);
     91         //add to y
     92         m_add(temp,y,y);
     93         //calculate x^(1+n/2)+...+x^n
     94         Matrix temp2;
     95         m_pow_with_saved(x_p,n>>1,temp2);
     96         Matrix temp3;
     97         m_multiple(temp,temp2,temp3);
     98         //add to y
     99         m_add(temp3,y,y);
    100         if(n&1)
    101         {
    102             //calculate x^(n-1)
    103             m_multiple(temp2,temp2,temp3);
    104             //calculate x^n
    105             m_multiple(temp3,x_p[1],temp2);
    106             //add x^n
    107             m_add(temp2,y,y);
    108         }
    109     }
    110 
    111 }
    112 
    113 //计算x^1 x^2 x^4 ...,然后调用求幂和的地方
    114 void m_pow_sum(Matrix x, unsigned int n, Matrix y)
    115 {
    116     //calculate x^1 x^2 x^4 ... x^logn
    117     unsigned int i=0,logn,n2=n;
    118     for(logn=0,n2=n;n2;logn++,n2 >>= 1);
    119     Matrix *pow_arry=new Matrix[logn==0?2:(logn+1)];
    120     m_one(pow_arry[0]);
    121     m_copy(x,pow_arry[1]);
    122     for(i=1;i<logn;i++)
    123     {
    124         m_multiple(pow_arry[i],pow_arry[i],pow_arry[i+1]);
    125     }
    126 
    127     m_pow_sum1(pow_arry,n,y);
    128     delete []pow_arry;
    129 }
    130 
    131 int main(void)
    132 {
    133 #ifndef ONLINE_JUDGE
    134     freopen("in.txt", "r", stdin);
    135 #endif
    136 
    137     map<int, int> index;
    138     int n;
    139     while(scanf("%d", &n) == 1)
    140     {
    141         index.clear();
    142         int ind = 0;
    143         Matrix a;
    144         m_zero(a);
    145         for(int i = 0; i < n; i++)
    146         {
    147             int u, v;
    148             scanf("%d %d", &u, &v);
    149             if(!index.count(u))
    150                 index[u] = ind++;
    151             if(!index.count(v))
    152                 index[v] = ind++;
    153             a[index[u]][index[v]]++;
    154         }
    155         ndim = ind;
    156 
    157         int m;
    158         scanf("%d", &m);
    159         for(int i = 0; i < m; i++)
    160         {
    161             int u, v, t1, t2;
    162             scanf("%d %d %d %d", &u, &v, &t1, &t2);
    163             //防止u,v未出现过。
    164             if(!index.count(u) || !index.count(v))
    165             {
    166                 printf("0\n");
    167                 continue;
    168             }
    169             u = index[u], v = index[v];
    170             if(t1 > t2)
    171             {
    172                 t1 = t1 ^ t2;
    173                 t2 = t1 ^ t2;
    174                 t1 = t1 ^ t2;
    175             }
    176             if(!t2)
    177             {
    178                 printf("0\n");
    179                 continue;
    180             }
    181             Matrix presum, tolsum;
    182             if(t1 > 1)
    183             {
    184                 m_pow_sum(a, t1 - 1, presum);
    185                 m_pow_sum(a, t2, tolsum);
    186                 printf("%d\n", ((tolsum[u][v] - presum[u][v]) % mod + mod) % mod);
    187             }
    188             else
    189             {
    190                 m_pow_sum(a, t2, tolsum);
    191                 printf("%d\n", ((tolsum[u][v] % mod) + mod) % mod);
    192             }
    193         }
    194     }
    195     return 0;
    196 }
  • 相关阅读:
    set使用
    css盒子模型详解一
    列表页调用当前栏目的子类织梦标签
    织梦如何在导航栏下拉菜单中调用当前栏目子类
    HDU1812
    BZOJ1485: [HNOI2009]有趣的数列
    组合数学学习笔记
    Full_of_Boys训练2总结
    Full_of_Boys训练1总结
    FFT算法学习笔记
  • 原文地址:https://www.cnblogs.com/cchun/p/2619517.html
Copyright © 2011-2022 走看看