标签:
百度百科:
http://baike.baidu.com/link?url=O0QvxbOY8SVBjrIl6nF6EvMHSslgcEIxfXSoty5SbkA7QjbWZjTWARzwTQsKKbSD5mlASljndZrqYjle_qwcmq#reference-[1]-4700690-wrap
模板:
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <string> 9 #include <set> 10 #include <functional> 11 #include <numeric> 12 #include <sstream> 13 #include <stack> 14 #include <map> 15 #include <queue> 16 #include <deque> 17 //#pragma comment(linker, "/STACK:102400000,102400000") 18 #define CL(arr, val) memset(arr, val, sizeof(arr)) 19 20 #define ll long long 21 #define INF 0x7f7f7f7f 22 #define lc l,m,rt<<1 23 #define rc m + 1,r,rt<<1|1 24 #define pi acos(-1.0) 25 26 #define L(x) (x) << 1 27 #define R(x) (x) << 1 | 1 28 #define MID(l, r) (l + r) >> 1 29 #define Min(x, y) (x) < (y) ? (x) : (y) 30 #define Max(x, y) (x) < (y) ? (y) : (x) 31 #define E(x) (1 << (x)) 32 #define iabs(x) (x) < 0 ? -(x) : (x) 33 #define OUT(x) printf("%I64d\n", x) 34 #define lowbit(x) (x)&(-x) 35 #define Read() freopen("a.txt", "r", stdin) 36 #define Write() freopen("b.txt", "w", stdout); 37 #define maxn 1010 38 #define maxv 1010 39 #define mod 1000000000 40 using namespace std; 41 42 struct edge 43 { 44 int to,weight; 45 }; 46 vector<edge>adjmap[maxn]; //动态邻接表 47 bool in_queue[maxn]; //顶点是否在队列中 48 int in_sum[maxn];//顶点入队次数 49 int dist[maxn];//源点到各点的最短路径 50 int path[maxn]; //存储到达i的前一个顶点 51 int nodesum; //顶点数 52 int edgesum; //边数 53 54 bool SPFA(int source) 55 { 56 deque<int>dq; 57 int i,j,x,to; 58 for(int i=1;i<=nodesum;i++) 59 { 60 in_sum[i]=0; 61 in_queue[i]=false; 62 dist[i]=INF; 63 path[i]=-1; 64 } 65 dq.push_back(source); 66 in_sum[source]++; 67 dist[source]=0; 68 in_queue[source]=true; 69 //初始化 完成 70 while(!dq.empty()) 71 { 72 x=dq.front(); //取出队首元素 73 dq.pop_front(); 74 in_queue[x]=false; //访问标记置0 ,同一个顶点可以访问多次,只要dist值变小 75 for(i=0;i<adjmap[x].size();i++) 76 { 77 to=adjmap[x][i].to; 78 if((dist[x]<INF)&&(dist[to]>dist[x]+adjmap[x][i].weight)) 79 { 80 dist[to]=dist[x]+adjmap[x][i].weight; 81 path[to]=x; //记录路径 82 if(!in_queue[to]) 83 { 84 in_queue[to]=true; 85 in_sum[to]++; //访问次数加1 86 if(in_sum[to]==nodesum) return false; //访问次数等于 顶点数 存在负权回路 87 if(!dq.empty()) 88 { 89 if(dist[to]>dist[dq.front()]) dq.push_back(to); //大的加入 队尾 90 else dq.push_front(to); //小的加入队首 91 } 92 else dq.push_back(to); //队列为空加入队尾 93 } 94 } 95 } 96 } 97 } 98 99 void Prit_Path(int x) 100 { 101 stack<int>s; 102 int w=x; 103 while(path[w]!=-1) //用栈保存路径 104 { 105 s.push(w); 106 w=path[w]; 107 } 108 cout<<"顶点1到顶点"<<x<<"最短路径长度为:"<<dist[x]<<endl; 109 cout<<"所经过的路径为:1 "; 110 while(!s.empty()) 111 { 112 cout<<s.top()<<" "; 113 s.pop(); 114 } 115 cout<<endl; 116 } 117 int main() 118 { 119 freopen("a.txt","r",stdin); 120 int i,s,e,w; 121 edge temp; 122 // cout<<"输入顶点数和边数:"; 123 cin>>nodesum>>edgesum; 124 for(int i=1;i<=nodesum;i++) adjmap[i].clear(); 125 for(int i=1;i<=edgesum;i++) 126 { 127 // cout<<"输入第"<<i<<"条边的起点,终点还有对应的权值:"; 128 cin>>s>>e>>w; 129 temp.to=e; 130 temp.weight=w; 131 adjmap[s].push_back(temp); 132 } 133 if(SPFA(1)) 134 { 135 for(int i=2;i<=nodesum;i++) Prit_Path(i); 136 } 137 else cout<<"图中存在负权回路"<<endl; 138 return 0; 139 }
标签:
原文地址:http://www.cnblogs.com/nowandforever/p/4571413.html