poj 3613 Cow Relays

来源:互联网 发布:淘宝直通车怎么卡位 编辑:程序博客网 时间:2024/05/17 01:17

题意:

已知起点 s 与终点 e,要求走 N 条边的最短路。

思路:

应用动态规划的思维。

邻接矩阵上的乘法,应用快速幂。

参考论文:*俞华程《矩阵乘法在信息学中的应用》

PS:

网上解题报告看过很多,但我觉得推导中都偏重与 floyd 算法。

论文里邻接矩阵乘法的内容,很好的解释了,为什么答案是一个矩阵连乘的结果。

纪念一下这道题。

/*无向图,已知起点和终点,要求走严格 N 条边的最短路。点数 <= 200N <= 1000000邻接矩阵上的乘法,应用快速幂。*俞华程《矩阵乘法在信息学中的应用》*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 110;struct M{int mm[maxn][maxn];M(){memset( mm, -1, sizeof(mm) );}}mat, tmat;int cnt, f[1000010];int k, m, s, e;int min( int a, int b ){ return a < b ? a : b; }void init(){memset( f, 0, sizeof(f) );cnt = 0;}M matMul( M mat, M tmat ){M temp;int i, j, t;for( i = 1; i <= cnt; i++ ){for( j = 1; j <= cnt; j++ ){for( t = 1; t <= cnt; t++ ){if( tmat.mm[t][j] != -1 && mat.mm[i][t] != -1 && ( temp.mm[i][j] == -1 || temp.mm[i][j] > mat.mm[i][t] + tmat.mm[t][j] ) )temp.mm[i][j] = mat.mm[i][t] + tmat.mm[t][j];}}}return temp;}int main(){scanf( "%d%d%d%d", &k, &m, &s, &e );int i, u, v, w;init();for( i = 0; i < m; i++ ){scanf( "%d%d%d", &w, &u, &v );if( !f[u] )f[u] = ++cnt;if( !f[v] )f[v] = ++cnt;tmat.mm[f[u]][f[v]] = tmat.mm[f[v]][f[u]] = w;}int num = 0;while( k ){if( k & 1 ){if( !num ){mat = tmat;num = 1;}else mat = matMul( mat, tmat );}tmat = matMul( tmat, tmat );k >>= 1;}printf( "%d\n", mat.mm[f[s]][f[e]] );return 0;}


原创粉丝点击