POJ 3613 Cow Relays

题意:求经过K条边 S和E点之间的最短路。

思路:floyd通过一个点k去更新i j两点的距离。那么N-1次floyd则通过N-1个点来更新i j之间的距离那么在i j中间恰好N条边。

        首先需要离散化点。然后用类似于快速幂的方法进行floyd,把加的操作换成松弛操作。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>

using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=110;

map<int,int> Map;
int N,T,S,E;

struct Matrix{
    int m[MAXN][MAXN];
    Matrix()
    {
        memset(m,-1,sizeof(m));
    }
};

Matrix mtMul(Matrix A, Matrix B)
{
    int i, j, k, tmp;
    Matrix C;
    for(i = 0; i < Map.size(); i ++)
        for(j = 0; j < Map.size(); j ++)
            for(k = 0; k < Map.size(); k ++)
            {
                if(A.m[i][k] == -1 || B.m[k][j] == -1)
                    continue;
                tmp = A.m[i][k] + B.m[k][j];
                if(C.m[i][j] == -1 || C.m[i][j] > tmp)
                    C.m[i][j] = tmp;
            }
    return C;
}

Matrix mtPow(Matrix A, int k)
{
    if(k == 1) return A;
    Matrix B = mtPow(A, k / 2);
    if(k % 2 == 0)
        return mtMul(B, B);
    else
        return mtMul(mtMul(B, B), A);
}
int main()
{
    while(scanf("%d%d%d%d",&N,&T,&S,&E)!=EOF)
    {
        int cnt=0;
        Map.clear();
        int u,v,w;
        Matrix G;
        for(int i=0;i<T;i++)
        {
            scanf("%d%d%d",&w,&u,&v);
            if(Map.find(u)==Map.end())
                Map[u]=cnt++;
            if(Map.find(v)==Map.end())
                Map[v]=cnt++;
            G.m[Map[u]][Map[v]]=G.m[Map[v]][Map[u]]=w;
        }
        Matrix ans=mtPow(G,N);
        printf("%d\n",ans.m[Map[S]][Map[E]]);
    }
    return 0;
}
View Code

 

posted on 2015-08-24 17:08  onlyAzha  阅读(114)  评论(0编辑  收藏  举报

导航