• POJ 3613 Cow Relays


    • 题目大意:给定起点和终点,求经过k条边的最短路

    • 思路:倍增Floyd 矩阵快速幂优化

      其实,虽然被称作倍增Floyd,但和Floyd关系好像并不大?

      按dp思想理解,设f(k,i,j)表示经过k条边从ij的最小花费,则

      (f(k,i,j)=min(f(k-1,i,p)+f(1,p,j)))

      k次Floyd显然会超时,现考虑定义新运算如下:

      对一张有n个点的图,用n*n的邻接矩阵来存储,其中(i,j)表示从i到j的最短路长度

      A矩阵表示经过x条边以后的最短路,B矩阵表示经过y条边以后的最短路

      定义新运算:(A*B=C)

      (C[i,j]=min_{k=1}^nA[i,k]+B[k,j])

      对这种矩阵运算,满足结合律,可以用类似快速幂的倍增思想进行优化

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=210;//注意空间限制 数组开大直接报错
    int s,e,k,n,m,book[3005];
    struct data {//离散化用
        int from,to,dis;
    } node[3005];
    struct Matrix {
        int mp[maxn][maxn];
        inline Matrix () {memset(mp,0x3f,sizeof(mp));}
        Matrix operator *(const Matrix &a)const {
            Matrix c;
            for(int k=1; k<=n; ++k) 
                for(int i=1; i<=n; ++i) 
                    for(int j=1; j<=n; ++j)
                        c.mp[i][j]=min(c.mp[i][j],mp[i][k]+a.mp[k][j]);
            return c;
        }
    } f,ans;
    void ksm(){
        ans=f;
        while(k) {
            if(k&1) ans=ans*f;
            f=f*f;
            k>>=1;
        }
    }
    int main() {
        scanf("%d%d%d%d",&k,&m,&s,&e);
        for(int i=1,x,y,z; i<=m; ++i) {
            scanf("%d%d%d",&z,&x,&y);
            book[++n]=x;
            book[++n]=y;
            node[i].from=x;
            node[i].to=y;
            node[i].dis=z;
        }
        sort(book+1,book+1+n);
        int tot=unique(book+1,book+1+n)-(book+1);
        for(int i=1; i<=m; ++i) {
            node[i].from=lower_bound(book+1,book+1+tot,node[i].from)-book;
            node[i].to=lower_bound(book+1,book+1+tot,node[i].to)-book;
            f.mp[node[i].from][node[i].to]=f.mp[node[i].to][node[i].from]=node[i].dis;
        }
        s=lower_bound(book+1,book+1+tot,s)-book;
        e=lower_bound(book+1,book+1+tot,e)-book;
        n=tot;
        //以上为离散化内容
        --k;//经过k条边 需要进行k-1次floyd
        ksm();
        printf("%d",ans.mp[s][e]);
        return 0;
    }
    
  • 相关阅读:
    双机调试环境部署
    VC++中通过MultiByteToWideChar将string|char*转换为wstring|wchar_t*
    Unicode环境下的类型转换
    SQL调优日记之发挥SQL性能与你的写法有关--对比三种方式实现相同功能
    从MS SQL删除大数据说开去
    Microsoft SQL Server Reporting Services (SSRS)报表技巧之在图表中增加参考线
    想个法子找出性能差的SQL
    MS SQL,数据库增长时众多表中谁是你关注的目标
    TSQL 日期处理总结
    投入.NET,我的第一篇BLOG
  • 原文地址:https://www.cnblogs.com/yu-xing/p/10423708.html
Copyright © 2020-2023  润新知