spfa 模板
题目:给出图的条件 ,求1到n的最短路
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; #define M 1009 #define INF 0x3f3f3f3f struct edge { int to,w;//保存边的信息,包括边的终点以及权值 }; int dis[M]; //最短距离的估计值(当前该点的最短距离) bool inq[M]; //标记该点是否在队列之中 vector<edge> g[M]; //利用一个vector保存,g[i]表示以i为起点的所有边的信息 int n,m,ee; void spfa(int u) { for(int i = 0;i <= n;i++) //初始化 { dis[i] = INF; //将估计值都初始化为INF inq[i] = false; //初始化为不在队列中 } dis[u] = 0; //起点的估计值直接就是0 inq[u] = true; //加入队列并进行标记 queue<int> q; q.push(u); while(!q.empty()) { u = q.front(); inq[u] = false; q.pop(); for(int i = 0;i < g[u].size();i++) { int v = g[u][i].to; //找出这条边对应的终点 int w = g[u][i].w; //这条边对应的权值 if(dis[v] > dis[u]+w) //如果终点的最短距离比起点的最短距离加上这条边的权值那么就更新 { dis[v] = dis[u]+w; if(!inq[v]) //如果v点的最短距离有所更新并且不在队列中,就将其加入队列。 { //否则就不需要重复加入队列增加不必要的操作。 inq[v] = true; //加入队列并标记 q.push(v); } } } } } int main() { while(scanf("%d %d %d",&n,&m,&ee)==3) { for(int i = 0;i <= n;i++) //清空vector避免多kase相互影响 g[i].clear(); for(int i = 0;i < m;i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); edge e; e.to = b;e.w = c; g[a].push_back(e); //e.to = a; //g[b].push_back(e); //题目中有说从a到b有这条路,并不是双向的。 } int s; scanf("%d",&s); for(int i = 0;i < s;i++) { int a; scanf("%d",&a); edge e; e.to = a; e.w = 0; g[0].push_back(e); //将家里到起点的权值设为0 //e.to = 0; //g[a].push_back(e); //从起点到家里是否有路其实无关紧要,因为思考一下有路的话 起点到起点也是0,所以根本不影响结果 } spfa(0); //printf("debug-----%d\n",dis[ee]); if(dis[ee]==INF) printf("-1\n"); else printf("%d\n",dis[ee]); } return 0; }