洛谷P2886 [USACO07NOV]Cow Relays G (矩阵乘法与路径问题)
本题就是求两点间只经过n条边的最短路径,定义广义的矩阵乘法,就是把普通的矩阵乘法从求和改成了取最小值,把内部相乘改成了相加。
代码包含三个内容:广义矩阵乘法,矩阵快速幂,离散化;
1 #include2 using namespace std; 3 const int INF=0x3f3f3f3f; 4 const int N=120; 5 int Hash[1000005],cnt=0;//用于离散化 6 struct matrix{ 7 int m[N][N]; 8 }ans,a; 9 10 matrix operator*(const matrix& a,const matrix& b){//定义广义矩阵乘法 11 matrix c; 12 memset(c.m,INF,sizeof(c.m)); 13 for(int i=1;i<=cnt;i++) 14 for(int j=1;j<=cnt;j++) 15 for(int k=1;k<=cnt;k++) 16 c.m[i][j]=min(c.m[i][j],a.m[i][k]+b.m[k][j]); 17 return c; 18 } 19 20 matrix pow_matrix(matrix a,int n){ 21 ans=a; 22 n--;//矩阵初值ans=M 23 while(n){ 24 if(n&1) ans=ans*a; 25 a=a*a; 26 n>>=1; 27 } 28 return ans; 29 } 30 31 int main(){ 32 int n,t,s,e; 33 scanf("%d%d%d%d",&n,&t,&s,&e); 34 memset(a.m,INF,sizeof(a.m)); 35 while(t--){ 36 int u,v,w; 37 scanf("%d%d%d",&w,&u,&v); 38 if(!Hash[u]) Hash[u]=++cnt; 39 if(!Hash[v]) Hash[v]=++cnt;//对点离散化 40 a.m[Hash[u]][Hash[v]]=a.m[Hash[v]][Hash[u]]=w;//邻接矩阵存图思想 41 } 42 ans=pow_matrix(a,n); 43 printf("%d",ans.m[Hash[s]][Hash[e]]); 44 return 0; 45 }