经过n条边的最短路
题意:给出一个有向图,求出经过n条边的最短路。
开始的时候把题意理解错了。 后来才明白过来。 这样的话就要用矩阵乘法了、
这说明一个问题就是当按照一个原则变化的时候,并且变化很多次的时候,可以考虑矩阵乘法加速。
View Code
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <queue> #include <map> using namespace std; const int N = 205, INF = 1<<29; int mp[N][N], n, m, s, t; void init() { int tp = 0; map<int,int>g; int u, v, w; for(int i=1; i<N; i++) for(int j=1; j<N; j++) { mp[i][j] = INF; } for(int i=1; i<=m; i++) { scanf("%d%d%d", &w, &u, &v); if(g.count(u) == 0) g[u] = ++tp; if(g.count(v) == 0) g[v] = ++tp; mp[g[u]][g[v]] = w; mp[g[v]][g[u]] = w; } s = g[s]; t = g[t]; m = tp; } void mul(int a[][N], int b[][N]) { int c[N][N]; for(int i=1; i<=m; i++) { for(int j=1; j<=m; j++) c[i][j] = INF; } for(int k=1; k<=m; k++) { for(int i=1; i<=m; i++) { for(int j=1; j<=m; j++) c[i][j] = min(c[i][j], a[i][k]+b[k][j]); } } for(int i=1; i<=m; i++) { for(int j=1; j<=m; j++) a[i][j] = c[i][j]; } } void solve() { int a[N][N] = {0}, b[N][N]; for(int i=1; i<=m; i++) { for(int j=1; j<=m; j++) { b[i][j] = mp[i][j]; a[i][j] = INF; } a[i][i] = 0; } while(n) { if(n&1) mul(a,b); mul(b,b); n = n>>1; } printf("%d\n",a[s][t]); } int main() { while(scanf("%d%d%d%d", &n, &m, &s, &t) != EOF) { init(); solve(); } return 0; }


浙公网安备 33010602011771号