Floyd求最短路
题目描述: 给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。
再给定k个询问,每个询问包含两个整数x和y,表示查询从点x到点y的最短距离,如果路径不存在,输出“impossible”。
数据保证图中不存在负权回路。
模板理解: 在没有负环的图里,求多源最短路,此算法本质上是DP的思想。注意在判断两点之间是否有最短路时,虽然两点之间距离初始化为INF ,但由于图中存在负权边,经过 Floyd ( O(n^3) )后,可能会使原本没有通路的两点之间距离小于 INF ,但不会小太多。
Code:
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 210;
int dis[N][N];
int n,m,k;
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++) // 初始化
for(int j=1;j<=n;j++)
if(i==j) dis[i][j] = 0;
else dis[i][j] = INF;
int x,y,z;
while(m--){
scanf("%d%d%d",&x,&y,&z);
dis[x][y] = min(dis[x][y],z); //处理重边
}
floyd();
while(k--){
scanf("%d%d",&x,&y);
if(dis[x][y] < INF/2) printf("%d\n",dis[x][y]); // 当两点之间不可达时,经过floyd后,其可能不为INF ,因为存在负权边
else printf("impossible\n");
}
return 0;
}