题意:
图已经给出,-1代表无路,给你一个点,和很多个点,求很多个点到这个点的最短路,并升序输出。
题解:
构造个反图,此题就变成了从一个点到很多个点的最短路。
#include <stdio.h>
#include<string.h>
#include<algorithm>
#define MX 1111111
using namespace std;
int map[30][30],n,p[30],dest,s[30];
struct point
{
int time,path[30],pos,org,pre,flag; //pos 为path数组中的位置,pre为他的路径传递关系,flag为他是否是消防局
}aa[30];
void dijkstra(int v0)
{
for(int i=1;i<=n;i++)//初始化
{
if(map[v0][i]!=-1)
aa[i].time=map[v0][i];
else
aa[i].time=MX;
aa[i].org=i;
aa[i].pos=1;
s[i]=0;
if(p[i])
aa[i].flag=1;
else
aa[i].flag=0;
aa[i].path[0]=i;
if(map[v0][i]!=-1)
aa[i].pre=v0;
else
aa[i].pre=-1;
}
s[v0]=1;aa[v0].pre=-1;
for(int i=1;i<=n;i++)
{
int min=MX,u;
for(int j=1;j<=n;j++)
{
if(!s[j]&&aa[j].time<min)
{
min=aa[j].time;
u=j;
}
}
s[u]=1;
// printf("u=%d\n",u);
for(int i=1;i<=n;i++)
{
if(!s[i]&&map[u][i]!=-1&&map[u][i]+aa[u].time<aa[i].time)
{
aa[i].time=aa[u].time+map[u][i];
aa[i].pre=u;
}
}
}
}
bool cmp(point a,point b)
{
return a.time<b.time;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(p,0,sizeof(p));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&map[j][i]);
scanf("%d",&dest);
while(1)
{
int w;
scanf("%d",&w);
p[w]=1;
char ch=getchar();
if(ch=='\n') break;
}
dijkstra(dest);
for(int i=1;i<=n;i++)
{
int u=i;
while(aa[u].pre!=-1)
{
aa[i].path[aa[i].pos++]=aa[u].pre;
u=aa[u].pre;
}
}
sort(aa+1,aa+n+1,cmp);
// printf("!%d %d\n",aa[6].time,aa[6].org);
printf("Org\tDest\tTime\tPath\n");
for(int i=1;i<=n;i++)
{
if(aa[i].flag)
{
printf("%d\t%d\t%d\t",aa[i].org,dest,aa[i].time);
for(int j=0;j<aa[i].pos-1;j++)
{
printf("%d\t",aa[i].path[j]);
}
printf("%d\n",aa[i].path[aa[i].pos-1]);
}
}
}
return 0;
}