POJ3613 Cow Relays 最短路+矩阵乘法
Posted WDZRMPCBIT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3613 Cow Relays 最短路+矩阵乘法相关的知识,希望对你有一定的参考价值。
题意:求恰好经过K条边的最短路
题解:根据Floyd的性质,如果我拿一开始给出的两个边权矩阵(只经过一条边的最短路的邻接矩阵)跑Floyd,得到的一定是只经过两条边的最短路的邻接矩阵(普通的Floyd是用求出的最短路来更新最短路而非用初始矩阵),同理用两条边的邻接矩阵一定能得到四条边的,因此N条边的邻接矩阵一定能由N/2条边的邻接矩阵得到,而当N为奇数时,用N-1的和初始矩阵跑一边就好了。因此套用矩阵乘法和快速幂的思想,就能把复杂度压倒N^2logN。
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN=1000+2; int N,M,K,S,T,a[MAXN][MAXN],b[MAXN][MAXN],t[MAXN][MAXN],m[MAXN]; bool flag; void Matrix_Copy(int a[MAXN][MAXN],int b[MAXN][MAXN]){ for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) a[i][j]=b[i][j]; } void Floyd(int a[MAXN][MAXN],int b[MAXN][MAXN],int c[MAXN][MAXN]){ memset(t,0X3F,sizeof(t)); for(int k=1;k<=N;k++) for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) if(t[i][j]>b[i][k]+c[k][j]) t[i][j]=b[i][k]+c[k][j]; Matrix_Copy(a,t); } void Quick_Floyd(int a[MAXN][MAXN],int y){ if(y&1) Matrix_Copy(b,a),flag=1; while(y>>=1){ Floyd(a,a,a); if(y&1) if(!flag) Matrix_Copy(b,a),flag=1; else Floyd(b,a,b); } } int main(){ memset(a,0X3F,sizeof(a)); scanf("%d %d %d %d",&K,&M,&S,&T); for(int i=1,u,v,w;i<=M;i++){ scanf("%d %d %d",&w,&u,&v); if(!m[u]) m[u]=++N; if(!m[v]) m[v]=++N; if(a[m[u]][m[v]]>w) a[m[u]][m[v]]=a[m[v]][m[u]]=w; } Quick_Floyd(a,K); cout << b[m[S]][m[T]] << endl; return 0; }
以上是关于POJ3613 Cow Relays 最短路+矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章
poj 3613 Cow Relays矩阵快速幂+Floyd