- 西科大新成立了一个WS旅行社。现在在全校范围内招收导游,旅行社为前来应聘的同学设计了一道难题:给应聘者一张地图,看他能否很快的计算出从出发点到达终点的最短路径,这个问题,相信对于来自西科大的你来说,是轻而易举的事情,但是作为旅行社的社长,Bearboy 还要求应聘者能够在地图中画出这条最短路。
- Input
- 输入的第一行为一个整数T(T组测试数据<=100)
- 对于每一组测试数据,第一行为两个整数 N,M。N表示地图上的景点个数(N<=2000)。(1 . 2 . 3....N),M表示道路个数。接下来是M行,每行包括三个整数 S .T .L,表示 景点S与景点T之间的距离是L(L<=1000)
- 最后一行是两个整数st 和 en ,表示旅行的 起点 和 目的地。
- Output
- 对于每组测试数据,输出包括两行,第一行是从st到en的最短路径长度。
- 第二行是输出从起点到目的地所经过的所有景点(如Sample output所示) 以先后顺序输出,数据保证只有一条最优路径
- 如果不能到达就输出 none!
- 每组测试数据后输出一个空行。
- Sample Input
- Raw
- 1
- 5 8
- 1 2 1
- 1 4 10
- 2 3 5
- 2 4 1
- 2 5 12
- 3 4 1
- 3 5 1
- 5 4 8
- 1 5
- Sample Output
- Raw
- Case 1 : 4
- 1 2 4 3 5
- 感谢万能的火山哥。
- 代码:
-
#include<bits/stdc++.h> using namespace std; const int maxn=2005; const int INF=0x7FFFFFFF;//无穷大 int pre[maxn];//记录一个前驱 int dis[maxn];//记录距离 int path[maxn];//记录路径 bool vis[maxn];//标记点 int head[maxn];//存边 int n,m; int tot,cnt; /*struct node//两种方法建立邻接表存图 { int v,w,next; node(){} node(int v,int w,int next):v(v),w(w),next(next){} }E[maxn*maxn]; void add(int u,int v,int w) { E[tot]=node(v,w,head[u]); head[u]=tot++; }*/ struct node { int v,w,next; }E[maxn*maxn]; void add(int u,int v,int w) { E[tot].v=v; E[tot].w=w; E[tot].next=head[u]; head[u]=tot++; } void init() { tot=0; memset(vis,false,sizeof((vis))); memset(head,-1,sizeof(head)); } void spfa(int st) { for(int i=1;i<=n;i++) { vis[i]=false; dis[i]=INF; } queue<int>q; q.push(st); int now,next; dis[st]=0; vis[st]=true; pre[st]=-1; while(!q.empty()) { now=q.front(); q.pop(); vis[now]=false;//对于弹出队列的就不需要再进入队列了 for(int i=head[now];i!=-1;i=E[i].next) { next=E[i].v; if(dis[next]>dis[now]+E[i].w)//类似于三角形两边之和大于第三边,是不是就走距离短的那边了 { dis[next]=dis[now]+E[i].w; pre[next]=now;//需要记录一下这个点的前驱,对于输出路径有用 if(!vis[next])//如果这点不在队列里面,就把他加如队列然后再找,就这样一直找 { vis[next]=true; q.push(next); } } } } } void print(int x)//递归输出路径,每次找到当前点的前驱就可以了 { if(pre[x]==-1) return; print(pre[x]); path[++cnt]=x;//放在后面是正着存的,输出就是正着输出的 } int main() { int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++) { init(); scanf("%d%d",&n,&m); int u,v,w; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } int st,en; scanf("%d%d",&st,&en); spfa(st); if(dis[en]==INF)//初始化为INF,那么如果终点距离还是INF,那么就说明没有找到最短路径 { printf("Case %d : none!\n",cas); printf("\n"); continue; } cnt=0; path[++cnt]=st; print(en); printf("Case %d : %d\n",cas,dis[en]); for(int i=1;i<=cnt;i++) { if(i<cnt) printf("%d ",path[i]); else printf("%d\n",path[i]); } printf("\n"); } return 0; }
PowerOJ 1799(spfa求最短路+路径输出)
最新推荐文章于 2021-08-15 23:40:17 发布