最短路径 Floyed解法

Floyed算法:0(n3) ; 可以处理负权边 ; 不能判断存在负回路

关键思路:点--中转点--点 与 点--点 的比较
最短路径

给定一个 n个点 m条边构成的无重边和自环的无向连通图。点的编号为 1∼n。请问:

1.从 11 到 n的最短距离。

2.去掉 k条边后,从 11 到 n的最短距离。


补充 1 一般用0x3f3f3f3f来表示无限大。

常memset(f , 0x3f , sizeof f )来将f[]中的值赋值为无限大,

但是单独说:0x3f =63 ;0x3f3f = 16191 ;0x3f3f3f = 4144959 ;0x3f3f3f3f = 1061109567,

而memset()是对char操作,即一个字节一个字节的操作,如果此时初始化的变量a为int类型(4字节),且0x表示16进制,进行了数据转换!

补充 2 void *memcpy(void*a, const void *b, size_t n)函数表示将size_t n个b中数拷如a中。

memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节!.

是覆盖而不是代替!

补充 3 typedef关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。


#include <bits/stdc++.h>
using namespace std;
//利用typedef关键字给pair<int,int>数据类型取别名为PII
typedef pair<int,int> PII ;
int t ,n , m , k ,x ,y ,z ;
int jl[1230][1230] ,dis[1230][1230];//初始 距离
PII zs[1230] ;//储存两点
void floyed()
{
    for(int s = 1 ;s <= n ; s ++ )//中转点
        for (int i = 1; i <= n; i++)//前
            for (int j = 1; j <= n; j++)//后
            {
                if (dis[i][j] > dis[i][s] + dis[s][j]) dis[i][j] = dis[i][s] + dis[s][j];
            }
    
}
int main()
{
    cin >> t ;
    while(t--)
    {
        cin >> n >> m >> k ;
        memset(jl,0x3f3f3f,sizeof jl) ;
        for(int i = 1 ; i <= m ; i ++)
        {
            cin >> x >> y >> z ;
            jl[x][y] = jl[y][x] = z ;//储存x-y之间距离
            zs[i] = {x,y};
        }
        memcpy(dis,jl,sizeof dis) ;//将jl[]拷入dis[]
        floyed();
        cout << dis[1][n] << endl ;
        //删除边后的
        memcpy(dis,jl,sizeof dis) ;
        for(int i = 1 ; i <= k ; i ++)//k个空,代表连接了k组
        {
            int del ;
            cin >> del ;
            dis[zs[del].first][zs[del].second] = 0x3f3f3f ;//将其转化为无穷大--》删除
            dis[zs[del].second][zs[del].first] = 0x3f3f3f ;
        }
        floyed();
        if(dis[1][n] > 0x3f3f3f/2) cout << -1 <<endl;
        else cout << dis[1][n] << endl ;
    }
    return  0;
}

(最短路径问题未完,待续)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值