SPFA
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int MAX_V = 1100; 8 const int MAX_E = 110000; 9 const int INF = 0x3f3f3f3f; 10 11 struct ENode 12 { 13 int to; 14 int w; 15 int Next; 16 }; 17 ENode edegs[MAX_E]; 18 int Head[MAX_V], tnt; 19 void Add_ENode (int a, int b, int w) 20 { 21 ++ tnt; 22 edegs[tnt].to= b; 23 edegs[tnt].w= w; 24 edegs[tnt].Next= Head[a]; 25 Head[a]= tnt; 26 ++ tnt; 27 edegs[tnt].to= a; 28 edegs[tnt].w= w; 29 edegs[tnt].Next= Head[b]; 30 Head[b]= tnt; 31 } 32 33 int Dis[MAX_V]; 34 bool visit[MAX_V]; //是否已经遍历过; 35 int que[MAX_V]; // 模拟队列; 36 int outque[MAX_V]; //记录每个点出队列的次数,防止有负边,保证无负边的图可以省略; 37 bool SPFA(int s, int n) 38 { 39 /*s:起点; n:点的总数*/ 40 int iq; //队列中元素个数; 41 memset(Dis, INF, sizeof(Dis)); 42 memset(visit, false, sizeof(visit)); 43 memset(outque, 0, sizeof(outque)); 44 iq= 0; 45 que[iq ++]= s; 46 visit[s]= true; 47 Dis[s]= 0; 48 int i= 0; 49 while (i< iq) 50 { 51 int u= que[i]; 52 visit[u]= false; 53 outque[u] ++; 54 if (outque[u]> n) return false; //当一个点进出队列超过n 次,必然有负边存在; 55 56 for (int k= Head[u]; k!= -1; k= edegs[k].Next) 57 { 58 /*bfs,和Dijkstra相似*/ 59 int v= edegs[k].to; 60 if (Dis[v]> Dis[u]+ edegs[k].w) 61 { 62 Dis[v]= Dis[u]+ edegs[k].w; 63 if (! visit[v]) 64 { 65 visit[v]= true; 66 que[iq ++]= v; 67 } 68 } 69 } 70 i ++; 71 } 72 return true; 73 } 74 75 void into() 76 { 77 /**初始化*/ 78 memset(Head,-1,sizeof(Head)); 79 tnt= -1; 80 } 81 82 int main() 83 { 84 int n, m; 85 int a, b, w; 86 while (~ scanf("%d %d", &n, &m)) 87 { 88 into(); 89 for (int i= 0; i< m; i ++) 90 { 91 scanf("%d %d %d", &a, &b, &w); 92 Add_ENode(a, b, w); 93 } 94 SPFA(1, n); 95 printf("%d\n", Dis[n]); 96 } 97 return 0; 98 }