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

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

void outprint(PtrGNode G){

int i,j;

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

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

if(G->GData[i][j]!=infinite)

printf("%d ",G->GData[i][j]);

else

printf(“∞”);

}

printf(“\n”);

}

}

void putlu(int u,int v)

{

//通过v结点的上一结点查找到u结点,将路径存到栈s中,最后输出。

int s[60],k,i,l;

k=0;

l=path[v];//将3对应的上一个点1 入栈了 然而3并没有进数组

while(l!=u)//入栈

{

s[k++]=l;

l=path[l];

}

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 有两条路,那么在更新最短路径时

//需要经过m的话,那么m的路数将赋值给 更新的结点

}

}

}

//这个循环主要是处理相同的最短路径

while(1){

int m = -1;

int min = infinite;

//求取最小值

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

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

1200页Java架构面试专题及答案

小编整理不易,对这份1200页Java架构面试专题及答案感兴趣劳烦帮忙转发/点赞

百度、字节、美团等大厂常见面试题

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
;

path[i] = m;

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

//需要经过m的话,那么m的路数将赋值给 更新的结点

}

}

}

//这个循环主要是处理相同的最短路径

while(1){

int m = -1;

int min = infinite;

//求取最小值

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

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

1200页Java架构面试专题及答案

小编整理不易,对这份1200页Java架构面试专题及答案感兴趣劳烦帮忙转发/点赞

[外链图片转存中…(img-PktR5AAR-1714408054456)]

[外链图片转存中…(img-nSO18waK-1714408054457)]

百度、字节、美团等大厂常见面试题

[外链图片转存中…(img-LOFVIjzK-1714408054457)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值