⬅ 返回

1、算法分析

2、例题

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,边权可能为负数。

再给定 k 个询问,每个询问包含两个整数 xy,表示查询从点 x 到点 y 的最短距离,如果路径不存在,则输出 impossible

数据保证图中不存在负权回路。

3、代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define PI 3.14159
using namespace std;
 
typedef pair<int,int> PII;
typedef long long LL;
const int MAX_INT =  0x3f3f3f3f;
const int N = 1e3+15;
const int mod = 1e9+7;
 
int n; 
int g[N][N];//邻接表
 
 
void floyd()
{
    for(int k=1;k<=n;k++)//k一定要放在最外层 i j 不要求
    {
        for(int i=1;i<=n;i++)
    	{
		    for(int j=1;j<=n;j++)
		    {
				g[i][j]=min(g[i][j],g[i][k]+g[k][j]);//对邻接表进行更新
		    }
	    }
        
    }
}
 
void solve()
{
	int m,k;
	cin>>n>>m>>k;
	memset(g,0x3f,sizeof g);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(i==j)g[i][j]=0;//这里要把所有顶点到自身的距离设为0 因为是多源汇 有多个顶点
	while(m--)
	{
		int x,y,z;
		cin>>x>>y>>z;
		g[x][y]=min(g[x][y],z);
	}
	floyd();
	
	while(k--)
	{
		int x,y;
		cin>>x>>y;
		//这里也不是等于MAX_INT 因为最大值也会被负权变更新
		if(g[x][y]>=MAX_INT/2)cout<<"impossible"<<endl;
		else cout<<g[x][y]<<endl;
	}
	
 
}
 
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 
    int T = 1;
    while(T--)
    {
        solve();
    }
}