zoukankan      html  css  js  c++  java
  • POJ 3613 floyd+矩阵快速幂

    题意:
    求s到e恰好经过n边的最短路
    思路:
    这题已经被我放了好长时间了。
    原来是不会矩阵乘法,快速幂什么的也一知半解

    现在终于稍微明白了点了

    其实就是把矩阵乘法稍微改改 改成能够满足结合律的矩阵“加法”,也就是floyd的步骤。
    这里写图片描述
    这里写图片描述
    这里写图片描述

    我就直接把集训队论文放上来吧。。。。(证明它满足结合率的,,,现在我看着还是懵逼的) 希望以后回头看的时候能够看懂吧

    注意这里初始化的时候自己到自己的权值不能赋成零。。因为这个WA了一会儿

    // by SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int c[1000050],cnt=0;
    int n,t,s,e,xx,yy,zz;
    struct matrix{
        int a[205][205];
        void init(){memset(a,0x3f,sizeof(a));}
    }map,cpy;
    matrix add(matrix &a,matrix &b){
        matrix jy;jy.init();
        for(int i=1;i<=cnt;i++)
            for(int j=1;j<=cnt;j++)
                for(int k=1;k<=cnt;k++)
                    jy.a[i][j]=min(a.a[i][k]+b.a[k][j],jy.a[i][j]);
        return jy;
    }
    void pow(matrix &ans,int x){
        while(x){
            if(x&1)ans=add(ans,cpy);
            cpy=add(cpy,cpy);
            x>>=1;
        }
        printf("%d
    ",ans.a[c[s]][c[e]]);
    }
    int main(){
        map.init();
        scanf("%d%d%d%d",&n,&t,&s,&e);
        for(int i=1;i<=t;i++){
            scanf("%d%d%d",&zz,&xx,&yy);
            if(!c[xx])c[xx]=++cnt;
            if(!c[yy])c[yy]=++cnt;
            map.a[c[xx]][c[yy]]=map.a[c[yy]][c[xx]]=zz;
        }
        for(int i=1;i<=cnt;i++)
            for(int j=1;j<=cnt;j++)
                cpy.a[i][j]=map.a[i][j];
        pow(map,n-1);
    }

    这里写图片描述

  • 相关阅读:
    让你在PC上调试Web App,UC浏览器发布开发者版
    多态
    深入理解DIP、IoC、DI以及IoC容器
    设计模式之迪米特原则(LOD)(最少知识原则)
    设计模式之合成/聚合利用原则(CARP)
    设计模式之接口隔离原则(ISP)
    设计模式之依赖倒转原则(DIP)
    设计模式之里氏代换原则(LSP)
    OO设计原则
    SQL分页
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532391.html
Copyright © 2011-2022 走看看