总体上,用个Dijkstra算法
稍加修改就行
经测试,救援经过的城市不会超过50;
相同长度的路径数不会超10;
如果结构直接设个500的数组会占太多内存而崩掉
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 65535
struct zlh{
int vis;//是否已经找出
int u;//存路程
int g;//存一共有几条路径
int ru[10][50];//ru 这个二维数组用来存路径
int p[10];//存若干条路径的长度
};
int jc[500][500]={0};
int main(){
struct zlh yu[500]={};
for(int i=0;i<=499;i++)
yu[i].g=1;
int a,b,m1,n1,y=0,ui[1000]={};
scanf("%d%d%d%d",&a,&b,&m1,&n1);
for(int i=0;i<a;i++)
scanf("%d",&ui[i]);
ui[999]=ui[0];
ui[0]=ui[m1];
ui[m1]=ui[999];
for(int i=1;i<=b;i++){
int u,m,r;
scanf("%d%d%d",&u,&m,&r);
if(!u) u=m1;//先写了以0为起点的算法,后来发现看错了 不想改,就加了个补丁.
else if(u==m1) u=0;
if(!m) m=m1;
else if(m==m1) m=0;
jc[u][m]=r;
jc[m][u]=r;
}
for(int i=1;i<a;i++)
for(int t=1;t<a;t++)
jc[i][t]=!jc[i][t]||i==t?INF:jc[i][t];
for(int i=1;i<a;i++){
yu[i].u=!jc[0][i]?INF:jc[0][i];
}
while(++y<a){
int min=INF,k=0;
for(int i=1;i<a;i++){
if(!yu[i].vis&&yu[i].u<min){
min=yu[i].u;
k=i;
}
}
for(int i=1;i<a;i++){
if(yu[i].u>jc[k][i]+min){
yu[i].g=yu[k].g;
yu[i].u=jc[k][i]+min;
for(int q=1;q<=yu[k].g;q++){
yu[i].p[q]=yu[k].p[q];
for(int t=0;t<=yu[k].p[q];t++)
yu[i].ru[q][t]=yu[k].ru[q][t];
yu[i].ru[q][++yu[i].p[q]]=k;
}
}
else if(yu[i].u==jc[k][i]+min){
for(int q=1;q<=yu[k].g;q++){
yu[i].p[++yu[i].g]=yu[k].p[q];
for(int t=0;t<=yu[k].p[q];t++)
yu[i].ru[yu[i].g][t]=yu[k].ru[q][t];
yu[i].ru[yu[i].g][++yu[i].p[yu[i].g]]=k;
}
}
}
yu[k].vis=1;
}
if(!n1) n1=m1;
printf("%d",yu[n1].g);
int se=0,sr=0;
for(int i=1;i<=yu[n1].g;i++){
int gh=0;
for(int t=0;t<=yu[n1].p[i];t++){
gh+=ui[yu[n1].ru[i][t]];
}
gh+=ui[n1];
if(gh>se){
sr=i;
se=gh;
}
}
printf(" %d\n",se);
for(int i=0;i<=yu[n1].p[sr];i++){
if(yu[n1].ru[sr][i]==0) printf("%d ",m1);
else if(yu[n1].ru[sr][i]==m1) printf("%d ",0);
else printf("%d ",yu[n1].ru[sr][i]);
}
printf("%d\n",n1==m1?0:n1);
}