zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    localStorage、sessionStorage详解,以及storage事件使用
    企业和开发人员究竟该如何适应web标准?
    平面设计常用制作尺寸
    git命令
    TCP/IP、Http、Socket的区别
    canvas
    《千克》
    《小数的加法》
    fiddler设置代理
    《分数的基本性质》
  • 原文地址:https://www.cnblogs.com/Zinn/p/8799178.html
Copyright © 2011-2022 走看看