SDUT 2143 图结构练习——最短路径 SPFA模板,方便以后用。。
图结构练习——最短路径
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
给定一个带权无向图,求节点1到节点n的最短路径。
输入
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表节点个数和边的个数。(n<=100)
剩下m行每行3个正整数a b c,代表节点a和节点b之间有一条边,权值为c。
输出
每组输出占一行,仅输出从1到n的最短路径权值。(保证最短路径存在)
示例输入
3 2 1 2 1 1 3 1 1 0
示例输出
1 0
#include <cstdio> #include <vector> #include <queue> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f; const int ARRSIZE = 100; struct edge{ int to, w; }; int n, m; vector<edge>map[ARRSIZE+10]; bool inque[ARRSIZE+10]; //是否在队列里 int dist[ARRSIZE+10]; //最短路径值 int vexcnt[ARRSIZE]; //结点入队次数,用来判断有无负环 bool spfa(int s) //起点为s { queue<int>q; for(int i = 1; i <= n; i++) //初始化 dist[i] = INF; dist[s] = 0; memset(inque, 0, sizeof(inque)); memset(vexcnt, 0, sizeof(vexcnt)); q.push(s); inque[s] = 1; vexcnt[s]++; while(!q.empty()) { int u = q.front(); q.pop(); inque[u] = 0; for(int i = 0; i < map[u].size(); i++) { int to = map[u][i].to; if(dist[u] < INF && dist[to] > dist[u] + map[u][i].w) { dist[to] = dist[u] + map[u][i].w; if(!inque[to]) { q.push(to); inque[to] = 1; vexcnt[to]++; if(vexcnt[to] >= n) //入队超过n次就出现负环 return false; } } } } return true; } int main() { int u, v, w; struct edge tmp; while(scanf("%d %d", &n, &m) != EOF) { for(int i = 1; i <= n; i++) //清空 map[i].clear(); while(m--) { scanf("%d %d %d", &u, &v, &w); tmp.to = v; tmp.w = w; map[u].push_back(tmp); //两条有向边 tmp.to = u; map[v].push_back(tmp); } spfa(1); printf("%d\n", dist[n]); } return 0; }