经过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;
 }

 

 

posted @ 2012-09-24 17:52  Gu Feiyang  阅读(190)  评论(0)    收藏  举报