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;
}
(最短路径问题未完,待续)