/** Dijkstra 算法模板 Dijkstra用法一:做预处理,可以计算从起点出发到每个点的最短路,即单源最短路 这道题还要注意的一个地方是,题目给了几条边是无向边的时候,如果分类讨论从哪条无向边走, 要考虑两个端点做起点,也是这个题我wa的地方。 **/ #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <stack> using namespace std; const int INF=1<<27; const int maxn=1005; struct HeapNode//优先队列的节点 { int d,u; bool operator < (const HeapNode& rhs) const { return d>rhs.d; } }; struct Edge { int from,to,dist; Edge(int a,int b,int c) { from=a; to=b; dist=c; } }; struct Dijkstra { int n,m;//点数和边数 vector<Edge> edges; //边列表 vector<int> G[maxn]; //每个几点出发的边编号(从0开始编号) bool done[maxn]; //是否已经永久标号 int d[maxn]; //s到各个点之间的距离 int p[maxn]; //最短路中的上一条边 void init(int n) { this->n=n; for(int i=0;i<n;i++) { G[i].clear(); } edges.clear(); } void AddEdge(int from,int to,int dist) { edges.push_back((Edge){from,to,dist}); m=edges.size(); G[from].push_back(m-1); } void dijkstra(int s)//求s到所有点的距离 { priority_queue<HeapNode> Q; for(int i=0;i<n;i++) d[i]=INF; d[s]=0; memset(done,0,sizeof(done)); Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top(); Q.pop(); int u=x.u; if(done[u]) continue; done[u]=true; for(int i=0;i<G[u].size();i++) { Edge& e=edges[G[u][i]]; if(d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=u; Q.push((HeapNode){d[e.to],e.to}); } } } } }; struct shanye { int x,y,z; }sh[maxn]; stack<int> tmp; int main() { int n,s,e,m,x,y,z,k,i,kase=0; Dijkstra a,b; while(scanf("%d%d%d",&n,&s,&e)!=EOF) { s--;e--; if(kase!=0) printf("\n"); kase++; scanf("%d",&m); a.init(n); b.init(n); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); x--;y--; a.AddEdge(x,y,z); a.AddEdge(y,x,z); b.AddEdge(x,y,z); b.AddEdge(y,x,z); } a.dijkstra(s); b.dijkstra(e); scanf("%d",&k); for(i=0;i<k;i++) { scanf("%d%d%d",&x,&y,&sh[i].z); sh[i].x=x-1; sh[i].y=y-1; } int ans=a.d[e],res,res1,res2; for(i=0;i<k;i++) { if(ans>a.d[sh[i].x]+sh[i].z+b.d[sh[i].y]) { ans=a.d[sh[i].x]+sh[i].z+b.d[sh[i].y]; res=sh[i].x; res2=sh[i].y; } if(ans>a.d[sh[i].y]+sh[i].z+b.d[sh[i].x])//之前漏了这种情况...wa了无数次 { ans=a.d[sh[i].y]+sh[i].z+b.d[sh[i].x]; res=sh[i].y; res2=sh[i].x; } } while(!tmp.empty()) tmp.pop(); printf("%d",s+1); if(ans<a.d[e]) { res1=res; while(1) { if(res==s) break; tmp.push(res); res=a.p[res]; } while(!tmp.empty()) { printf(" %d",tmp.top()+1); tmp.pop(); } while(1) { if(res2==e) break; printf(" %d",res2+1); res2=b.p[res2]; } printf(" %d\n",e+1); printf("%d\n",res1+1); printf("%d\n",ans); } else { int e1=e; while(1) { if(e==s) break; tmp.push(e); e=a.p[e]; } while(!tmp.empty()) { printf(" %d",tmp.top()+1); tmp.pop(); } printf("\nTicket Not Used\n"); printf("%d\n",a.d[e1]); } } return 0; }
Dijkstra 单源最短路 模板 uva11374
最新推荐文章于 2023-02-11 21:43:10 发布