链接:
题意:
一个城市中有N个交叉路口,给出从一个交叉路口i到另一个交叉路口j所需要的时间(i,j=1~N,单向)如果edge[i][j]=-1 则表示不通
给出一个火警的位置(终点) 和X个消防站(起点)
输出:每一行描述了一个消防站的信息,这些信息按消防站到达火警位置所需时间从小到大排列。这些信息包括:消防站的位置(初始位置)、火警位置(目标位置)、所需时间以及最短路径上的每个交叉路口。
题解:
起点有多个,终点只有一个。为了只进行一次dijkstra算法 我们可以考虑从终点出发
如果是无向图 终点到起点和起点的距离是一样的。
而如果是有向图,只要进行一点小改动即可:在dij算法中将邻接矩阵edge[i][j] i和J的位置互换。路径则用path存 终点保存-1终止
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxx 0x3f3f3f3f int map[25][25]; int dis[25]; int vis[25]; int path[25]; struct node { int pos; int ans; //每个起点的时间排序 } endd[25]; int m,start; int cmp(node a,node b) { return a.ans<b.ans; } void dij() { int i,j,loc,minn; for(i=1; i<=m; i++) { dis[i]=map[i][start]; //i,j互换 path[i]=start; vis[i]=0; } vis[start]=1; path[start]=-1; for(i=1; i<m; i++) { minn=maxx; for(j=1; j<=m; j++) if(!vis[j]&&dis[j]<minn) minn=dis[j],loc=j; vis[loc]=1; for(j=1; j<=m; j++) if(!vis[j]&&dis[j]>dis[loc]+map[j][loc]) //i,j互换 { dis[j]=dis[loc]+map[j][loc]; path[j]=loc; } } return; } int main() { int i,j,t,n,s=0; scanf("%d",&m); for(i=1; i<=m; i++) for(j=1; j<=m; j++) { scanf("%d",&map[i][j]); if(map[i][j]==-1) map[i][j]=maxx; } scanf("%d",&start); dij(); while(~scanf("%d",&endd[s].pos)) { endd[s++].ans=dis[endd[s].pos]; } sort(endd,endd+s,cmp); printf("Org\tDest\tTime\tPath\n"); for(i=0;i<s;i++) { printf("%d\t%d\t%d",endd[i].pos,start,endd[i].ans); j=endd[i].pos; while(j!=-1) { printf("\t%d",j); j=path[j]; } cout<<endl; } return 0; }
时间: 2024-10-26 11:28:30