hdu 2544 【总结】 Dijkstra,Bellman-Ford ,SPFA 最短路求法及对应优化
题目地址:hdu2544
就是直接求最短路 数据很弱 什么方法都可以
1 floyd
#include<iostream> using namespace std; #define INF 10000009 int d[105][105]; int n,m; void init() { for(int i=0;i<n;i++) for(int j=0;j<n;j++) d[i][j]=(i==j?0:INF); } // 1 floyd 2 Dijkstra 3 Bellman-Ford 4 Dijkstra priority_queue 5 Bellman-Ford with queue int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int u,v,w; for(int i=0;i<m;i++) { cin>>u>>v>>w; d[u-1][v-1]=w; d[v-1][u-1]=w; } for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(d[i][k]!=INF&&d[k][j]!=INF)d[i][j]=d[i][j]<(d[i][k]+d[k][j])?d[i][j]:(d[i][k]+d[k][j]); cout<<d[0][n-1]<<endl; } }
2 Dijkstra 赤裸裸的小白书代码
#include<iostream> using namespace std; #define INF 10000009 int d[105]; int n,m; //struct //{ // int u; // int v; // int w; // //} e[10005]; int done[10005]; int w[105][105]; void init() { for(int i=0;i<n;i++) d[i]=(i==0?0:INF); memset(done, 0, sizeof(done)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) w[i][j]=(i==j?0:INF); } // 1 floyd 2 Dijkstra 3 Bellman-Ford 4 Dijkstra priority_queue 5 Bellman-Ford with queue int min(int a,int b) { return a<b?a:b; } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int a,b,c; for(int i=0;i<m;i++) { cin>>a>>b>>c; // e[i].u=a-1; // e[i].v=b-1; // e[i].w=c; w[a-1][b-1]=c; w[b-1][a-1]=c; } // Dijkstra for(int i=0;i<n;i++) { int x; int m=INF; for(int y=0;y<n;y++) if(done[y]==0&&d[y]<=m) m=d[x=y]; done[x]=1; for(int y=0;y<n;y++) if(w[x][y]!=INF) d[y]=min(d[y],d[x]+w[x][y]); } cout<<d[n-1]<<endl; } }
3 Dijkstra 使用优先队列优化
记住要将无向图转化为有向图
#include<iostream> #include<utility> #include<vector> #include<queue> using namespace std; #define INF 1000000009 typedef pair<int, int> pii; int d[1005]; int nxt[200010]; int first[1005]; int n,m; struct { int u; int v; int w; } e[200010]; int done[1005]; //int w[105][105]; void init() { for(int i=0;i<n;i++) d[i]=(i==0?0:INF); memset(done, 0, sizeof(done)); memset(first,-1,sizeof(first)); // for(int i=0;i<n;i++) // for(int j=0;j<n;j++) // w[i][j]=(i==j?0:INF); } // 1 floyd 2 Dijkstra 3 Bellman-Ford 4 Dijkstra priority_queue 5 Bellman-Ford with queue int min(int a,int b) { return a<b?a:b; } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int a,b,c; for(int i=0;i<m;i++) { cin>>a>>b>>c; e[i].u=a-1; e[i].v=b-1; e[i].w=c; nxt[i]=first[a-1]; first[a-1]=i; // w[a-1][b-1]=c; // w[b-1][a-1]=c; } for(int i=0;i<m;i++) { e[i+m].u=e[i].v; e[i+m].v=e[i].u; e[i+m].w=e[i].w; nxt[i+m]=first[e[i].v]; first[e[i].v]=i+m; } // Dijkstra with priority_queue; priority_queue<pii,vector<pii>,greater<pii> > pq; pq.push(make_pair(d[0], 0)); while(!pq.empty()) { pii u=pq.top(); pq.pop(); int x=u.second; if(done[x]) continue; done[x]=1; for(int i=first[x];i!=-1;i=nxt[i]) { int y=e[i].v; if(d[y]>d[x]+e[i].w) { d[y]=d[x]+e[i].w; pq.push(make_pair(d[y],y)); } } } cout<<d[n-1]<<endl; } }4 Bellman-Ford
#include<iostream> #include<utility> #include<vector> #include<queue> using namespace std; #define INF 1000000009 typedef pair<int, int> pii; int d[1005]; int n,m; struct { int u; int v; int w; } e[200010]; void init() { for(int i=0;i<n;i++) d[i]=(i==0?0:INF); } int min(int a,int b) { return a<b?a:b; } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int a,b,c; for(int i=0;i<m;i++) { cin>>a>>b>>c; e[i].u=a-1; e[i].v=b-1; e[i].w=c; } for(int i=0;i<m;i++) { e[i+m].u=e[i].v; e[i+m].v=e[i].u; e[i+m].w=e[i].w; } //Bellman-Ford for(int k=0;k<n-1;k++) { for(int i=0;i<2*m;i++) { int x=e[i].u; int y=e[i].v; if(d[x]<INF) d[y]=min(d[y],d[x]+e[i].w); } } cout<<d[n-1]<<endl; } }
5 使用队列优化的Bellman-Ford (SPFA)
#include<iostream> #include<utility> #include<vector> #include<queue> using namespace std; #define INF 1000000009 int d[105]; int first[105]; int nxt[20005]; int inq[105]; int n,m; struct { int u; int v; int w; } e[20005]; void init() { for(int i=0;i<n;i++) d[i]=(i==0?0:INF); memset(first, -1, sizeof(first)); } int min(int a,int b) { return a<b?a:b; } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int a,b,c; for(int i=0;i<m;i++) { cin>>a>>b>>c; e[i].u=a-1; e[i].v=b-1; e[i].w=c; nxt[i]=first[a-1]; first[a-1]=i; } for(int i=0;i<m;i++) { e[i+m].u=e[i].v; e[i+m].v=e[i].u; e[i+m].w=e[i].w; nxt[i+m]=first[e[i].v]; first[e[i].v]=i+m; } //Bellman-Ford with_queue SPFA queue<int> q; q.push(0); while(!q.empty()) { int x=q.front(); q.pop(); inq[x]=0; for(int i=first[x];i!=-1;i=nxt[i]) { int y=e[i].v; if(d[y]>d[x]+e[i].w) { d[y]=d[x]+e[i].w; if(!inq[y]) { inq[y]=1; q.push(y); } } } } cout<<d[n-1]<<endl; } }
需要注意的是 因为SPFA能处理负权值 ,所以 关键是 踢出队列以后 把在inq这个标记清除了
和在Dijkstra 中, 踢出队列仍然不用做任何操作
只需要维护done数组 ,已经做过就不要再进队 出队了(出队就是“进入A集合”) 然后更新后重新进入优先队列 因为只要进入 优先级一定比更新之前的那个pair高 那么一定会先完成done[x]=1 操作 ,没有扔掉的也无所谓了。
额
如果不喜欢向前星 用vector邻接表也行
这里还是全部重新用vector 打一遍
1用pq 维护的DIjkstra 使用vector版本
(注: 需要说明的是 ,这里的队列和SPFA里的队列完全不同 ,这里仅仅是取出当前d值最小的快速方法而SPFA里面的队列是是为了BFS)
代码:
#include<iostream> #include<vector> #include<utility> #include<queue> using namespace std; typedef pair<int,int> pii; #define INF 1000000009 int d[105]; int done[105]; vector<int> G[1000]; vector<int> E[1000]; int n,m; int min(int a,int b) { return a<b?a:b; } void init() { for(int i=0;i<n;i++) d[i]=(i==0?0:INF); for(int i=0;i<n;i++) // 取代前向星 { G[i].clear(); E[i].clear(); } memset(done, 0, sizeof(done)); } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int u,v,w; for(int i=0;i<m;i++) { cin>>u>>v>>w; G[u-1].push_back(v-1); G[v-1].push_back(u-1); E[u-1].push_back(w); E[v-1].push_back(w); } // Dijkstra with priority_queue priority_queue<pii,vector<pii>,greater<pii> >pq; pq.push(make_pair(d[0], 0)); while(!pq.empty()) { pii u=pq.top(); pq.pop(); int x=u.second; if(done[x]) continue; done[x]=1; int s=G[x].size(); for(int i=0;i<s;i++) { int y=G[x][i]; if(d[x]+E[x][i]<d[y]) { d[y]=d[x]+E[x][i]; pq.push(make_pair(d[y],y)); } } } cout<<d[n-1]<<endl; } }
2 SPFA vector版本
#include<iostream> #include<vector> #include<queue> using namespace std; #define INF 1000000009 int n,m; int d[105]; int inq[105]; vector<int> G[105]; vector<int> E[105]; void init() { for(int i=0;i<n;i++) d[i]=(i==0?0:INF); memset(inq, 0, sizeof(inq)); for(int i=0;i<n;i++) { G[i].clear(); E[i].clear(); } } int min(int a,int b) { return a<b?a:b; } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; init(); int u,v,w; for(int i=0;i<m;i++) { cin>>u>>v>>w; G[u-1].push_back(v-1); G[v-1].push_back(u-1); E[u-1].push_back(w); E[v-1].push_back(w); } // // for(int i=0;i<m;i++) // { // e[i+m].u=e[i].v; // e[i+m].v=e[i].u; // e[i+m].w=e[i].w; // } // SPFA queue<int> q; q.push(0); while(!q.empty()) { int x=q.front(); q.pop(); inq[x]=0; int s=G[x].size(); for(int i=0;i<s;i++) { int y=G[x][i]; if(d[y]>d[x]+E[x][i]) { d[y]=d[x]+E[x][i]; if(!inq[y]) { inq[y]=1; q.push(y); } } } } cout<<d[n-1]<<endl; } }
posted on 2014-03-19 04:10 814jingqi的ACM 阅读(125) 评论(0) 编辑 收藏 举报