基础实验6-2.5 城市间紧急救援

本文介绍了一种使用Dijkstra算法解决城市应急救援队伍调度问题的方法。在一张包含多个城市和快速道路的地图中,算法需找出从起点到目标点的最短路径,并沿途集结最多救援队伍。通过初始化、距离更新和最小值查找等步骤,实现了最优路径的计算。最终,算法能够输出最少时间和最大救援队伍数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

思路

此题目思路与以往的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--];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值