题目
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
思路
此题目思路与以往的Dijkstra的题目有不同,参考了网上的写法之后,才写出了此题,一些有坑的地方已经,单独注释了。
代码
/*
此题坑很多,虽然用到了Dijkstra算法但是,第一次循环到赋值是无效的,为了求路径条数,舍弃了第一次给dist赋值的情况
*/
#include<stdio.h>
#include<stdlib.h>
#define N 500
#define Max 65534
typedef struct stack{
int data[N];
int top;
}*stack;
void push(stack ss,int x);
void init();
void Dijkstra();
int findMin();
int pop(stack ss);
stack CreatStack(stack ss);
void Print();
int n,m,s,d;
int dist[N],visit[N],pathcount[N],CitySave[N],SaveCount[N],path[N];
int Dist[N][N];
stack S;
void main(){
scanf("%d %d %d %d",&n,&m,&s,&d);
init();
Dijkstra();
printf("%d %d\n",pathcount[d],SaveCount[d]);
Print();
system("pause");
}
void init(){
int i,j;
int vi,vj,x;
for(i=0;i<n;i++)
visit[i]=0;
for(i=0;i<n;i++)
pathcount[i]=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
Dist[i][j]=Max;
for(i=0;i<n;i++)
scanf("%d",&CitySave[i]);
for(i=0;i<m;i++){
scanf("%d %d %d",&vi,&vj,&x);
Dist[vi][vj]=x;
Dist[vj][vi]=x;
}
}
void Dijkstra(){
int v;
int i;
//visit[s]=1;
dist[s]=0;//使得第一次findmin返回的节点肯定是s节点
pathcount[s]=1;
path[s]=-1;//结束标志
SaveCount[s]=CitySave[s];
for(i=0;i<n;i++){
if(i!=s)//很重要,别忘了要不覆盖掉了
dist[i]=Dist[s][i];
}
while(1){
v=findMin();
printf("index=%d\n",v);
if(v==-1)
break;
visit[v]=1;
for(i=0;i<n;i++)
if(visit[i]==0 && Dist[v][i]<Max)
if(dist[v]+Dist[v][i]<dist[i]){
dist[i]=dist[v]+Dist[v][i];
pathcount[i]=pathcount[v];
path[i]=v;
SaveCount[i]=SaveCount[v]+CitySave[i];
}else if(dist[v]+Dist[v][i]==dist[i]){
pathcount[i]+=pathcount[v];
if(SaveCount[i]<SaveCount[v]+CitySave[i]){
SaveCount[i]=SaveCount[v]+CitySave[i];
path[i]=v;
}
}
}
}
void Print(){
int i;
S=CreatStack(S);
push(S,d);
while(path[d]!=-1){
push(S,path[d]);
d=path[d];
}
while(S->top!=-1){
printf(" %d",pop(S));
}
}
int findMin(){
int Min=Max,index;
int i;
for(i=0;i<n;i++)
if(visit[i]==0&&dist[i]<Min){
Min=dist[i];
index=i;
}
if(Min==Max)
return -1;
else
return index;
}
stack CreatStack(stack ss){
ss=(stack)malloc(sizeof(struct stack));
ss->top=-1;
}
void push(stack ss,int x){
ss->data[++ss->top]=x;
}
int pop(stack ss){
return ss->data[ss->top--];
}