BZOJ1706 cows Relay Race

This thing is good ideas.

The solution is taken into a matrix power adder min, like the multiplication into an addition, and is the same floyed. In this case, a matrix operation is equivalent to a shortest relaxation.

Process of building the matrix is ​​relatively simple and can be discrete, of course, below there is another better play, can learn from it.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;
int read(){
    int sum=0,f=1;char x=getchar();
    while(x<'0'||x>'9'){
        if(x=='-') f=-1;
        x=getchar();
    }while(x>='0'&&x<='9'){
        sum=sum*10+x-'0';
        x=getchar();
    }return sum*f;
}
int k,m,s,e,num;
int id[2000];
struct Matrix{
    int x[600][600];
    void add(int a,int b,int c){
        x[a][b]=c;
        return ;
    }
    friend Matrix operator * (Matrix a,Matrix b){
        Matrix c;
        memset(c.x,0x3f,sizeof(c.x));
        for(int i=1;i<=num;i++)
            for(int j=1;j<=num;j++)
                for(int k=1;k<=num;k++)
                    c.x[i][j]=min(c.x[i][j],a.x[i][k]+b.x[k][j]);
        return c;
    }
    void db(){
        cout<<endl;
        for(int i=1;i<=num;i++){
            for(int j=1;j<=num;j++)
                cout<<x[i][j]<<" ";
            cout<<endl;
        }
    }
    void put(int a,int b){
        printf("%d",x[a][b]);
        return ;
    }
}a;
void qpow(int k){
    Matrix c=a,b=a;
//    b.db();
    for(;k;k>>=1,b=b*b)
        if(k&1) c=c*b;
//    c.db();
    a=c;
}
int main(){
    k=read();m=read();s=read();e=read();
    memset(a.x,0x3f,sizeof(a.x));
    for(int i=1,x,y,z;i<=m;i++){
        z=read();x=read();y=read();
        id[x]=id[x]?id[x]:++num;
        id[y]=id[y]?id[y]:++num;
        a.add(id[x],id[y],z);
        a.add(id[y],id[x],z);
    }
//    a.db();
    qpow(k-1);
//    a.db();
    a.put(id[s],id[e]);
    return 0;
}
View Code

Such a play is made directly with the initial matrix, according to A n- = A * A n-. 1- done operation, since a start matrix is not clear who Yes.

Later figured out the reason why the previous matrix is so, is because the definition matrix is another matrix multiplication finish the matrix or the original matrix, the former is the reason why all the diagonal 1, because by matrix multiplication after this matrix to meet the matrix properties.

So the question is this matrix positive infinity matrix, because the matrix multiply any matrix or complete the original matrix (since taken min Well).

Guess you like

Origin www.cnblogs.com/Yu-shi/p/11203002.html