floyd modification - Bull

Cattle Station

Given a free edges made of T to view point number is an integer between 1 and 1000.

Shortest seek start point S to end point E from just after the N side (can be repeated through) a.

Note: Data guaranteed solvable.

Input format
Line 1: contains four integers N, T, S, E.

The second line 2 ... T + 1: Each line contains three integers, described in a long side edge and the number of edges constituting two points.

Output format
output an integer representing the length of the shortest path.

Data range
2≤T≤100,
2≤N≤106
input sample:
2. 6. 6. 4
. 11. 4. 6
. 4. 4. 8
. 8. 4. 9
. 6. 8. 6
2. 6. 9
. 3. 8. 9
Output Sample:
10

answer:

He said before the nature of floyd also dp, this question is to test fold increase floyd. We know that the traditional floyd f ( k , i , j ) f(k,i,j) represents the i to j through the first 1 k 1-k shortest path node, then we have here the meaning of modifications dp, i denotes the j right across the path length of k edges. So we are not into the transfer equation f ( a + b , i , j ) = f ( a , i , k ) + f ( b , k , j ) , k = ( 1 , n ) f(a+b,i,j)=f(a,i,k)+f(b,k,j),k=(1,n) then multiply this question Why can it? We analyze, we just go through from start to finish and m edges of this process, we will not change the total distance, so we first seek behind or in front of the result is the same, on his behalf is associative, so we can use a similar Quick thinking power demand answers. log level, without first add 1 plus 2 ... There is also an error-prone point, because we have changed the meaning of the array floyd, so we started the assignment of f [i] [i] can not be equal to 0 the , such as our distance from i to i through the edge of k (k> 0) 0 jump is likely to do?

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

using namespace std;

const int N = 210;

int k, n, m, S, E;
int g[N][N];
int res[N][N];

void mul(int c[][N], int a[][N], int b[][N])
{
    static int temp[N][N];
    memset(temp, 0x3f, sizeof temp);
    for (int k = 1; k <= n; k ++ )
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )
                temp[i][j] = min(temp[i][j], a[i][k] + b[k][j]);
    memcpy(c, temp, sizeof temp);
}

void qmi()
{
    memset(res, 0x3f, sizeof res);
    for (int i = 1; i <= n; i ++ ) res[i][i] = 0;

    while (k)
    {
        if (k & 1) mul(res, res, g);    // res = res * g
        mul(g, g, g);   // g = g * g
        k >>= 1;
    }
}

int main()
{
    cin >> k >> m >> S >> E;

    memset(g, 0x3f, sizeof g);
    map<int, int> ids;
    if (!ids.count(S)) ids[S] = ++ n;
    if (!ids.count(E)) ids[E] = ++ n;
    S = ids[S], E = ids[E];

    while (m -- )
    {
        int a, b, c;
        cin >> c >> a >> b;
        if (!ids.count(a)) ids[a] = ++ n;
        if (!ids.count(b)) ids[b] = ++ n;
        a = ids[a], b = ids[b];

        g[a][b] = g[b][a] = min(g[a][b], c);
    }

    qmi();

    cout << res[S][E] << endl;

    return 0;
}
Published 115 original articles · won praise 7 · views 1691

Guess you like

Origin blog.csdn.net/weixin_42979819/article/details/104072359