• poj3613Cow Relays——k边最短路(矩阵快速幂)


    题目:http://poj.org/problem?id=3613

    题意就是求从起点到终点的一条恰好经过k条边的最短路;

    floyd+矩阵快速幂,矩阵中的第i行第j列表示从i到j的最短路,矩阵本身代表一个边数状态;

    所以矩阵相乘就是floyd算法,两个矩阵相乘就得到它们所代表的边数相加边数的状态矩阵;

    原始矩阵自乘k-1次,过程中取min,就得到答案;

    因为只是自乘,所以可以使用快速幂。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,cnt,s,t,k,nd[1005];
    int rd()
    {
        char dc;
        int x=0,f=1;dc=getchar();
        while(dc<'0'||dc>'9')
        {
            if(dc=='-')f=-1;
            dc=getchar();
        }
        while(dc>='0'&&dc<='9')
        {
            x=x*10+(dc-'0');
            dc=getchar();
        }
        return x*f;
    }
    struct Matrix{
        int a[205][205];
        Matrix operator * (const Matrix &y)  const
        {
            Matrix x;
            memset(x.a,0x3f,sizeof x.a);
            for(int i=1;i<=cnt;i++)
                for(int j=1;j<=cnt;j++)
                    for(int k=1;k<=cnt;k++)
                        x.a[i][j]=min(x.a[i][j],a[i][k]+y.a[k][j]);
            return x;
        }
    }sid,ans;
    int main()
    {
        k=rd();n=rd();s=rd();t=rd();
        memset(sid.a,0x3f,sizeof sid.a);//
        for(int i=1;i<=n;i++)
        {
            int x,y,z;
            z=rd();x=rd();y=rd();
            if(!nd[x])nd[x]=++cnt;
            if(!nd[y])nd[y]=++cnt;
            sid.a[nd[x]][nd[y]]=sid.a[nd[y]][nd[x]]=z;
        }
        k--;//已经有连了一条边的矩阵 
        ans=sid;//同上意义 
        while(k)
        {
    //        if(k&1)ans+=sid.a[nd[s]][nd[t]];//不是普通加法
            if(k&1)ans=ans*sid;
            sid=sid*sid;
            k>>=1;
        }
        printf("%d",ans.a[nd[s]][nd[t]]);
        return 0;
    }
  • 相关阅读:
    一周以来工作总结关于位图索引
    再学学表的分区
    PostgreSQL学习笔记
    通过vc助手设置快捷注释
    c语言中unsigned类型和普通类型间的转换
    LVS环境搭建入门
    java学习路线
    linux下删除当前文件夹中按时间排序的前N个文件夹
    RHEL下安装jdk和tomcat
    TDD 强迫你 Program to Interface
  • 原文地址:https://www.cnblogs.com/Zinn/p/8799178.html
Copyright © 2020-2023  润新知