POJ 3613 Cow Relays

se经过n条边的最短路,看了08年国家集训队.俞华程的论文《矩阵乘法在信息学中的应用》,

其中讲到图的邻接矩阵k次方后,a[i][j]可以表示ij经过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;

}

 

 

 

你可能感兴趣的:(poj)