这道题目把矩阵跟图论完美地结合在了一起,矩阵与图论,本来就是难舍难分。能一下子想到相关知识,还是比较有难度
要看多点书嘞。
/* *题目大意: * 他知道中国有很多的名胜古迹,他知道自己在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 }