天天看点

AcWing spfa求最短路径 题解(spfa算法求 可以有负权边的最短路径 模板)(最短路径)

```cpp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int N = 1e5 + 10;

int h[N], ne[N], e[N], w[N], idx;
int dis[N];
int n, m;
bool st[N];

void add(int a, int b, int c){
	e[idx] = b;
	ne[idx] = h[a];
	w[idx] = c;
	h[a] = idx ++ ;
}

int spfa(){
	memset(dis, 0x3f, sizeof(dis));//初始化dis数组 
	dis[1] = 0;
	
	queue<int>q;//建立储存最短路径节点的队列,如果该节点已经是最短路径,可以用该节点修改其他节点的值,就让该节点入队 
	q.push(1);//初始节点入队
	st[1] = true;//利用st数组标记该节点已经入队
	        
	while(q.size()){//当队列不为空时 
		int t = q.front();//标记队首元素 
		q.pop();//队首元素出队
		st[t] = false;//标记该节点已出队 
		for(int i = h[t]; i != -1; i = ne[i]){//以标记的节点为首节点进行便利 
			int j = e[i];//标记元素
			if(dis[j] > dis[t] + w[i]){//如果被标记节点的距离值大于该节点到首节点的距离+首节点的距离值 
				dis[j] = dis[t] + w[i];//更新被标记节点的距离值 
				q.push(j);//将该节点入队 
				st[j] = true; //标记该节点已入队 
			} 
		} 
	} 
	return dis[n]; 
}

int main()
{
	cin>>n>>m;
	memset(h, -1, sizeof(h));//初始化邻接表 
	while(m -- ){
		int a, b, c;
		cin>>a>>b>>c;
		add(a, b, c);
	}
	int t = spfa();
	if(dis[n] == 0x3f3f3f3f) cout<<"impossible"<<endl;
	else{
		cout<<dis[n]<<endl;
	}
	return 0;
} 
           

继续阅读