求s到e经过n条边的最短路,看了08年国家集训队.俞华程的论文《矩阵乘法在信息学中的应用》,
其中讲到图的邻接矩阵k次方后,a[i][j]可以表示i到j经过n-1个点的一条路径,结合floyd就能求出我
们所需要的结果。
/*Accepted 2060K 172MS C++ 1608B 2012-09-15 10:38:47*/ #include <stdio.h> #include <string.h> #include <stdlib.h> const int MAXN = 1 << 10; const int MAXD = 105; int hash[MAXN]; int N; int n, t, s, e; struct Matrix { int val[MAXD][MAXD]; Matrix() { memset(val, -1, sizeof val); } }; Matrix MatrixMul(Matrix A, Matrix B) { int i, j, k, temp; Matrix C; for(k = 1; k <= N; k ++) { for(i = 1; i <= N; i ++) { for(j = 1; j <= N; j ++) { if(A.val[i][k] == -1 || B.val[k][j] == -1) //i,j不能通过k点连通 continue; temp = A.val[i][k] + B.val[k][j]; if(C.val[i][j] == -1 || temp < C.val[i][j]) C.val[i][j] = temp; } } } return C; } Matrix MatrixPow(Matrix A, int k) { if(k == 1) return A; Matrix B = MatrixPow(A, k / 2); if(k & 1) return MatrixMul(MatrixMul(B, B), A); else return MatrixMul(B, B); } int main() { while(scanf("%d%d%d%d", &n, &t, &s, &e) != EOF) { Matrix A; int len, u, v; N = 1; memset(hash, -1, sizeof hash); while(t --) { scanf("%d%d%d", &len, &u, &v); if(hash[u] == -1) hash[u] = N ++; if(hash[v] == -1) hash[v] = N ++; A.val[hash[u]][hash[v]] = len; A.val[hash[v]][hash[u]] = len; } N --; A = MatrixPow(A, n); printf("%d\n", A.val[hash[s]][hash[e]]); } return 0; }
浙公网安备 33010602011771号