2015-01-04 16:54:53
以Hdu 2544 为测试平台,浅结回顾最短路各类算法。
First:Bellman-Ford(边权可为负,可找负圈,复杂度:O(V*E))
思路回顾:如果不存在负圈,那么最短路不会经过一个点两次,那么最短路长度<= V-1,对全图进行V-1次松弛,每次松弛检查每条边,如果dis[to] > dis[from] + cost则更新。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 typedef pair<int,int> pii; 20 const int INF = (1 << 30) - 1; 21 const int maxn = 110; 22 23 int N,M,ecnt; 24 int dis[maxn]; 25 26 struct edge{ 27 int u,v,cost; 28 }e[maxn * maxn]; 29 30 int Bellman_ford(int s){ 31 for(int i = 1; i <= N; ++i) 32 dis[i] = INF; 33 dis[s] = 0; 34 for(int k = 1; k < N; ++k){ 35 bool flag = false; 36 for(int i = 1; i <= ecnt; ++i){ 37 int u = e[i].u; 38 int v = e[i].v; 39 if(dis[u] != INF && dis[v] > dis[u] + e[i].cost){ 40 dis[v] = dis[u] + e[i].cost; 41 flag = true; 42 } 43 } 44 if(!flag) break; 45 } 46 return dis[N]; 47 } 48 49 void Add_edge(int u,int v,int c){ 50 e[++ecnt].u = u; 51 e[ecnt].v = v; 52 e[ecnt].cost = c; 53 54 e[++ecnt].u = v; 55 e[ecnt].v = u; 56 e[ecnt].cost = c; 57 } 58 59 int main(){ 60 int a,b,c; 61 while(scanf("%d%d",&N,&M) != EOF){ 62 if(N == 0 && M == 0) break; 63 ecnt = 0; 64 for(int i = 1; i <= M; ++i){ 65 scanf("%d%d%d",&a,&b,&c); 66 Add_edge(a,b,c); 67 Add_edge(b,a,c); 68 } 69 printf("%d\n",Bellman_ford(1)); 70 } 71 return 0; 72 }