【SSL 2510】[洛谷P2886] Cow Relays G【Matrix Multiplication】

Topic

l i n k link l i n k
Given an undirected connected graph with T edges, find the shortest path length from S to E through N edges.

Input format

Four positive integers in the first line N, T, S, EN, T, S, EN,T,S,E , the meaning is shown in the title.
Three positive integersw, u, vw, u, v ineach line of the next T linew,u ,v , respectively represent the length of the path, the start point and the end point.

Output format

An integer on a line represents the SSS toEEE passesNNThe shortest length of N sides.

Sample input and output

Enter #1

2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9

Output #1

10

analysis:

In fact, just make a small change to the matrix multiplication,
and then give these vertices a number, and then you can make the matrix of the adjacency matrix fast exponentiation.
Note that the shortest path is required, so overload the operator as '+''+'+ Transfern − 1 n-1
according to the inputinitial arraynJust 1 time.

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define reg register
using namespace std;
int u[1000005];
int n,s,t,e,tot,w,x,y;
const int N=505;
struct matrix{
    
    int F[N][N];}dis,C;
matrix operator +(const matrix &x,const matrix &y)
{
    
    
    matrix c;
    memset(c.F,0x3f3f3f3f,sizeof(c.F));
    for(reg int k=1;k<=tot;k++)
        for(reg int i=1;i<=tot;i++)
            for(reg int j=1;j<=tot;j++)
                c.F[i][j]=min(c.F[i][j],x.F[i][k]+y.F[k][j]);  //最短路
    return c;		
}
void check_x(){
    
    if(!u[x]) u[x]=++tot;}
void check_y(){
    
    if(!u[y]) u[y]=++tot;}
void build_map(int x,int y,int z){
    
    dis.F[x][y]=dis.F[y][x]=z;}
void Pre()
{
    
    
    memset(dis.F,0x3f3f3f3f,sizeof(dis.F));
    scanf("%d%d%d%d",&n,&t,&s,&e);
    for(reg int i=1;i<=t;i++)
    {
    
    
        scanf("%d%d%d",&w,&x,&y);
        check_x();check_y();  //编号
        build_map(u[x],u[y],w);  //邻接矩阵
    }
}
void ksm(int x)
{
    
    
	C=dis;
    while(x)
    {
    
    
        if(x&1) C=C+dis;
        dis=dis+dis;
        x>>=1;
    }
}
int main()
{
    
    
    Pre();
    ksm(n-1);  //转移n-1次
    printf("%d",C.F[u[s]][u[e]]);
    return 0;
}

Guess you like

Origin blog.csdn.net/dgssl_xhy/article/details/111404976