#C10L10P02. C10.L10.最短路算法.SPFA模板

C10.L10.最短路算法.SPFA模板

题目描述

给定一个 nn 个点 mm 条边的有向图,图中可能存在重边和自环, 边权可能为负数。请你求出 11 号点到 nn 号点的最短距离,如果无法从 11 号点走到 nn 号点,则输出 impossible。数据保证不存在负权回路。

输入格式

第一行包含整数 nnmm ( 1n,m1000001 \le n,m \le 100000 )。

接下来 mm 行每行包含三个整数 xxyyzz,表示存在一条从点 xx 到点 yy 的有向边,边长为 zz ( abs(z)10000abs(z) \le 10000 )。

输出格式

输出一个整数,表示 1 号点到 n 号点的最短距离。

如果路径不存在,则输出 impossible。

样例

3 3
1 2 5
2 3 -3
1 3 4
2

完成程序

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int dis[N], n, m;
bool f[N];
queue <int> que;
struct node { //邻接表
	int v;
	int next;
	int w;
	node(){
		v = next = w = 0;
	}
	node(int a, int b, int c) {
		v = a;
		next = b;
		w = c;
	}
}adj[N];
int head[N];
int idx = 1;

void insert(int a, int b, int c){
	adj[idx] = node(b, head[a], c);
	head[a] = idx;
	idx++;
}

void spfa(){
	dis[1] = 0;
	que.push(1);
	while (que.size()){
		int tem = __填空(1)__;//取出队头节点
		que.pop() ;
		__填空(2)__;//改变标志位
		for(int i=head[tem];i!=0;i = adj[i].next) {//把该节点相连的点更新
			int j = adj[i].v;
			if (__填空(3)__){
				dis[j] = dis[tem] + adj[i].w;
				if (f[j] == 0){
					que.push(j);
					f[j] = 1;
				}
			}
		}
	}
}
 
int main(){
	cin >> n >>m ;
	memset(dis, 0x3f3f3f3f, sizeof dis);
	for (int i=1; i<=m; i++) {
		int x, y,z;
		cin >> x >> y >> z;
		insert(x,y,z);
	}
	
	spfa();
	
	if (dis[n] > 0x3f3f3f3f / 2) cout<<"impossible"<< endl;
	else cout << dis[n] << endl;
	
	return 0;
}

填空(1):{{ input(1) }}

填空(2):{{ input(2) }}

填空(3):{{ input(3) }}