IT民工
加油!

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

 

 

 

posted on 2012-09-15 10:52  找回失去的  阅读(241)  评论(0)    收藏  举报