# 6-08. 城市间紧急救援（25）--Dijkstra

9 篇文章 0 订阅

6-08. 城市间紧急救援（25）题目地址

150 ms

65536 kB

8000 B

Standard

1
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
2 60
0 1 3
2
8 10 0 1
2 1 5 1 1 1 1 3
0 4 1
0 3 2
0 7 1
4 5 1
3 2 1
7 3 1
3 6 1
2 1 1
1 6 1
2 5 1
5 12
0 7 3 2 1
3
2 1 0 1
2 1
1 0 2
1 3
0 1

• dijkstra 经典应用变式，无论加上什么条件 解法都差不多
• 注意变量初始化，退出条件等
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>

using namespace std;

#define N 501
#define INF 99999999

int n, m, s, d;
int teams[N];
int mp[N][N];

bool vis[N];
int pre[N];
int amount[N];
int pathCount[N];
int dis[N];

void Dijkstra()
{
int i;
for (i = 0; i < n; i++)
{
pathCount[i] = 0;
vis[i] = false;
amount[i] = teams[i];
pre[i] = -1;
dis[i] = mp[s][i];
}
pathCount[s] = 1;
dis[s] = 0;
vis[s] = true;
int newP = s;

while (newP != d)
{
for (i = 0; i < n; i++)
{
if (!vis[i])
{
//
if (dis[newP] + mp[newP][i] < dis[i])
{
dis[i] = dis[newP] + mp[newP][i];
pathCount[i] = pathCount[newP];
amount[i] = amount[newP] + teams[i];
pre[i] = newP;
}
else if (dis[newP] + mp[newP][i] == dis[i])
{
pathCount[i] += pathCount[newP];
if (amount[newP] + teams[i] > amount[i])
{
amount[i] = amount[newP] + teams[i];
pre[i] = newP;
}
}
}// if
}// for

int minn = INF;
for (i = 0; i < n; i++)
{
if (!vis[i] && dis[i] < minn)
{
minn = dis[i];
newP = i;
}
}
vis[newP] = true;
}// while
}

int main()
{
//freopen("in", "r", stdin);
while (scanf("%d%d%d%d", &n,&m,&s,&d) != EOF)
{
int i,j;
for (i = 0; i < n; i++)
{
scanf("%d", &teams[i]);
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
mp[i][j] = INF;
}
mp[i][i] = 0;
}
int tmpi, tmpj,tmpdist;
for (i = 0; i < m; i++)
{
scanf("%d%d%d", &tmpi, &tmpj, &tmpdist);
mp[tmpi][tmpj] = tmpdist;
mp[tmpj][tmpi] = tmpdist;
}

Dijkstra();

printf("%d %d\n", pathCount[d], amount[d]);

vector<int> v;
int lenv = 0;
v.clear();
int vn = d;
while (vn != -1)
{
v.push_back(vn);
lenv++;
vn = pre[vn];
}
printf("%d", v[lenv-1]);
for (i = lenv-2; i >= 0; i--)
{
printf(" %d", v[i]);
}
printf("\n");
}
return 0;
}
• 1
点赞
• 0
收藏
• 打赏
• 0
评论
08-30 3378
11-16 3066
03-10 692
11-20 3266
11-03 3077
10-16 8073
01-29 3264
11-21 2492
12-08 861
07-28 1464
04-01 553
12-08 373
06-10 1452
08-20 1249

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

master-dragon

¥2 ¥4 ¥6 ¥10 ¥20

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