迪杰斯特拉算法求最短路。注意从i到j和从j到i用时是不同的,也就是是有向图。还有,最后要求的是从消防站到火警位置的最短用时,我因为这里没好好看题调了好久才发现。
最后递归打印路径即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Elem
{
int _time,_org,_dest;
};
bool cmp(Elem a,Elem b)
{
return a._time<b._time;
}
int p[25]= {0};
int pre[25]= {0};
void Out_put(int a)
{
if(pre[a]==-1)return;
printf("\t%d",pre[a]);
Out_put(pre[a]);
}
int main()
{
int N;
while(scanf("%d",&N)!=EOF)
{
int gl[25][25]= {0};
for(int i=1; i<=N; ++i)
for(int j=1; j<=N; ++j)
scanf("%d",&gl[i][j]);
char c;
int n=0;
memset(p,0,sizeof(p));
while(scanf("%d%c",&p[n++],&c)&&c!='\n');
int dis[25];
bool used[25]= {0};
memset(used,0,sizeof(used));
memset(dis,0x7f,sizeof(dis));
memset(pre,0,sizeof(pre));
int INF=dis[0];
dis[p[0]]=0;
pre[p[0]]=-1;
while(true)
{
int v=-1;
for(int i=1; i<=N; ++i)
if(!used[i]&&(v==-1||(dis[i]<dis[v]))) v=i;
if(v==-1) break;
used[v]=true;
for(int i=1; i<=N; ++i)
if(gl[i][v]!=-1&&dis[v]!=INF&&dis[i]>dis[v]+gl[i][v])
{
dis[i]=dis[v]+gl[i][v];
pre[i]=v;
}
}
Elem ans[25];
for(int i=1; i<n; ++i)
{
ans[i-1]._org=p[i];
ans[i-1]._dest=p[0];
ans[i-1]._time=dis[p[i]];
}
sort(ans,ans+n,cmp);
puts("Org Dest Time Path");
for(int i=0; i<n-1; ++i)
{
printf("%d\t%d\t%d\t%d",ans[i]._org,ans[i]._dest,ans[i]._time,ans[i]._org);
Out_put(ans[i]._org);
printf("\n");
}
}
return 0;
}