栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

floyed模板

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

floyed模板

引入

今天打算开始写模板了(

那就发在博客里好了。

简析

说明:f [ i ][ j ] 表示从 i 到 j 的距离。

floyed的思想就是先找到一个点 k ,然后依次遍历经过 k 的两个点 x,y 。

倘若原来记录 x 到 y 的距离大于 经过 x 经过 k 到 y的距离,就更新一下 x 到 y 的距离,即 f [ i ][ j ] = f [ i ][ k ] + f [ k ][ j ] 。

要注意的是它求的是最短路,所以要初始化 每个点到其他点的距离为 inf 。这里的 inf 是一个很大的值,保证更新的时候能找到最小值。

比方说,如果两点初始距离为 0,那如何也找不到更小的点更新了(除非是负数)。

而 f [ i ][ i ] 初始化为 0 ,因为自己到自己的距离显然是 0。(这里运用了显然论证法。

但如果要求的是最长路,那就不用初始化了。

特别注意

这里输出 impossible 的条件为 if ( f [ x ][ y ] > inf / 2 )。

因为题中说有负数的点,所以更新时也许会让不连通的点略小一点。

例如f [ i ][ k ]为负数,f [ k ][ j ] 不连通( inf ),f [ i ][ j ] 不连通( inf ),那就会更新 f [ i ][ j ] 使其略小于 inf 。

那题目中如果说没有负数,那条件就是 if( f  [ x ][ y ] == inf)。

上代码
#include
using namespace std;

inline int read(){//快读
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}

#define N 20010

#define inf 0x3f3f3f3f

int n,m,p,f[N][N];

int main(){
    n=read();m=read();p=read();
    for(int i=1;i<=n;i++){//初始化
        for(int j=1;j<=n;j++){
            if(i==j)
                f[i][j]=0;
            else
                f[i][j]=inf;
        }
    }
    for(int i=1;i<=m;i++){//读入
        int u,v,w;
        u=read();v=read();w=read();
        f[u][v]=min(f[u][v],w);//考虑题目可能会恶心你
    }
    for(int k=1;k<=n;k++){//找点
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(f[i][j]>f[i][k]+f[k][j])
                    f[i][j]=f[i][k]+f[k][j];
            }
        }
    }
    for(int i=1;i<=p;i++){//判断,输出
        int x,y;
        x=read();
        y=read();
        if(f[x][y]>inf/2)
            cout<<"impossible"<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738702.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号