7-35 城市间紧急救援 (25 分)(思路加详解)(1)

文章描述了一种优化的Dijkstra算法,用于解决单源点最短路径问题,考虑到达每个顶点的救援队数量,当遇到相同最短距离时,选择经过点的救援队数量最多的路径作为最优解。
摘要由CSDN通过智能技术生成

}

printf("%d ",u);

for(i=k-1;i>=0;i–)

printf("%d ",s[i]);

printf(“%d”,v);//3没有进数组

}

void Dijkstra(PtrGNode G){

int dist[1000];//存路径长度

int cist[1000];//记录人数 一直在变

int rist[1000];//存人数 到达每个顶点的人数不变

int vis[1000]={0};//记录已经遍历的点

int count[1000]; //记录最短路径条数

int i,j;//因为从begin开始的点 也有人数

if(G->Nv==2){//最短路径只有两个顶点

cist[end]=a[0]+a[1];

count[end]=1;

path[1]=0;

}

else

{

for(i=0;iNv;i++){

count[i]=1;

dist[i] = G->GData[begin][i];

if(i != begin)

cist[i] = a[begin]+a[i];

else

cist[i] = a[i];

}

vis[0]=1;

while (1)

{

int mv=-1;

int min=infinite;

for(i=0; iNv; i++){

if(vis[i] != 1 && dist[i] < min){

min=dist[i];

mv=i;

}

}

if(mv==-1)

break;

vis[mv]=1;

for(j=0;jNv;j++){

if(vis[j]!=1 && min+G->GData[mv][j]<dist[j]){

dist[j] = min+G->GData[mv][j];

cist[j] = cist[mv]+a[j];//根据路径长度已经判断 比原来路径短 而其人数必定时增加的

// rist[j]=rist[mv]+a[j];

count[j] = count[mv];

path[j] = mv;

}

else if(vis[j]!=1 && min+G->GData[mv][j] == dist[j]){//处理相同路径长度时 选择人数多的

count[j] += count[mv];

if((cist[mv]+a[j])>cist[j]){

cist[j] = cist[mv]+a[j];

// rist[j]=rist[mv]+a[j]; //更新 已经找到最短路径的那一个顶点 已经确认的到达这个顶点的总人数

path[j] = mv;

}

}

}

}

}

printf(“%d %d”,count[end],cist[end]);

printf(“\n”);

putlu(begin,end);

}

int main(){

PtrGNode G;

G=(PtrGNode)malloc(sizeof(struct GNode));

CreatGNode(G);

Dijkstra(G);

//outprint(G);

}

//2 1 0 1

//20 30

//0 1 2

//6 9 0 3

//10 20 30 40 50 60

//0 1 1

//0 2 3

//0 3 6

//0 4 3

//0 5 2

//1 2 2

//2 3 3

//3 4 3

//4 5 1

在这里插入图片描述

四:上超时的码(这是我二刷是做的,上面是第一次做的)

=========================================================================================

但这个超时间。我优化了但还是过去

/**

思路:

这个就是单源点最短路径的变形,这里是出现了到达某个顶点出现相同的最短距离,

只不过是经过的点不一样,每个点给了相应的赋值,我们需要判断每一条路径上经过的

点,他们的值相加(每个点赋值),比较最大的那个就是救援队人数最多的,

选取他们作为救援最优路径

*/

#include<bits/stdc++.h>

using namespace std;

#define infinite 9999

typedef struct GNode* PtrGraph;

typedef struct GNode{

int Nv;

int Ne;

int Date[501][501];

}gnode;

int N,M,S,D;

map<int,int>m;//用map容器进行储存每个结点的救援队数量

int path[501] = { S };//将路径的初始值设为开始的那个点

//邻接矩阵储存图

void createGraph(PtrGraph G){

cin >> N >> M >> S >> D;

G->Nv = N;

G->Ne = M;

for( int i = 0; i < N; i++ ){

int temp;

cin >> temp;

m[i] = temp;

}

//矩阵初始化

for( int i = 0; i < G->Nv; i++ ){

for( int j = 0; j < G->Nv; j++ ){

if( i == j )

G->Date[i][j] = 0;

else

G->Date[i][j] = infinite;

}

}

//矩阵赋值

for( int i = 0; i < G->Ne; i++ ){

int a,b,c;

cin >> a >> b >> c;

G->Date[a][b] = c;

G->Date[b][a] = c;

}

}

//输出矩阵

void outPutGNode(PtrGraph G){

int i,j;

for(i=0; iNv; i++){

for(j=0;jNv;j++){

if(G->Date[i][j] == infinite||G->Date[j][i] == infinite)

printf(“∞”);

else

cout << G->Date[i][j] << ’ ';

}

printf(“\n”);

}

}

//求路径上救援队数量

int PathSum( int x ){

int sum = m[x];

while( path[x] != x ){

x = path[x];

sum+=m[x];

}

return sum;

}

//求路径

void PathWay(int x){

stacks;

s.push(x);

while(path[x] != x ){

x = path[x];

s.push(x);

}

while( !s.empty() ){

if( s.size() != 1 )

cout << s.top() << ’ ';

else

cout << s.top();

s.pop();

}

}

//单源点最短路径

void dij(PtrGraph G){

int dist[501] = {0};

int visited[501] = {0};

int vis[501] = {0};

// int path[501] = { S };//将路径的初始值设为开始的那个点

int count[501];//记录路数

for( int i = 0; i < G->Nv; i++ ){

count[i] = 1;//初始化为1,即开始点到每个点的路数为1条

dist[i] = G->Date[S][i];//将开始的那一行赋值给dist

}

visited[S] = 1;

vis[S] = 1;

while(1){

int m = -1;

int min = infinite;

//求取最小值

for(int i = 0; i < G->Nv; i++ ){

if( dist[i] < min && visited[i] != 1){

min = dist[i];

m = i;

}

}

//说明没找到最小值 即代表访问完了,即便图是不连通的 那也求不出最小值了

if( m == -1 ){

break;

}

visited[m] = 1;

//更新

for( int i = 0; i < G->Nv; i++ ){

if( visited[i] != 1 && dist[m] + G->Date[m][i] < dist[i] ){

dist[i] = dist[m] = G->Date[m][i];

path[i] = m;

count[i] = count[m];//如果从开始的点S到 m 有两条路,那么在更新最短路径时

最后

image.png

infinite;

//求取最小值

for(int i = 0; i < G->Nv; i++ ){

if( dist[i] < min && visited[i] != 1){

min = dist[i];

m = i;

}

}

//说明没找到最小值 即代表访问完了,即便图是不连通的 那也求不出最小值了

if( m == -1 ){

break;

}

visited[m] = 1;

//更新

for( int i = 0; i < G->Nv; i++ ){

if( visited[i] != 1 && dist[m] + G->Date[m][i] < dist[i] ){

dist[i] = dist[m] = G->Date[m][i];

path[i] = m;

count[i] = count[m];//如果从开始的点S到 m 有两条路,那么在更新最短路径时

最后

[外链图片转存中…(img-aOwg3DvO-1714257066233)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值