给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出impossible。
数据保证不存在负权回路。
输入格式
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。
输出格式
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出”impossible”。
数据范围
1≤n,m≤105
,
图中涉及边长绝对值均不超过10000。
输入样例:
3 3
1 2 5
2 3 -3
1 3 4
输出样例:
2
给定一张图,对于图中的x,y,z,有d[y]<=d[x]+z成立那么就称为这条边满足三角形不等式,如果所有的边都满足三角形不等式,那么d数组就是所求的最短路径。算法流程:
1:首先建立一个队列,最初队列中只含有起点1;
2:取出对头元素x,扫描他的所有出边,(x,y,z),如果d[y]>d[x]+z,则使用d[x]+z更新d[y],同时y不在队列中,则把y入队
3:重复上述步骤,知道队列为空
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int head[N],ver[N],next1[N],d[N],edge[N];
int n,m,tot;
queue<int > q;
bool v[N];
void add(int x,int y,int z){
ver[++tot]=y;
edge[tot]=z;
next1[tot]=head[x];
head[x]=tot;
}
int spaf(){
memset(d,0x3f,sizeof d);
memset(v,0,sizeof v);
d[1]=0;
v[1]=1;
q.push(1);
while(q.size())
{
int x=q.front();
q.pop();
v[x]=0;
for(int i=head[x];i;i=next1[i])
{
int y=ver[i],z=edge[i];
if(d[y]>d[x]+z)
{
d[y]=d[x]+z;
if(!v[y])
q.push(y),v[y]=1;
}
}
}
return d[n];
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
int t=spaf();
if(t==0x3f3f3f3f)
cout<<"impossible";
else
printf("%d",d[n]);
return 0;
}