链接:
题意:
一个城市中有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;
}