【PAT 1003】 Emergency 图论Dijkstra

2024-04-05 06:18

本文主要是介绍【PAT 1003】 Emergency 图论Dijkstra,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1003. Emergency (25)

时间限制
400 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) - the number of cities (and the cities are numbered from 0 to N-1), M - the number of roads, C1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
Sample Output
2 4
题意:

求单源点对最短路径数和最大的点权重之和。

分析:

求最短路径数用dijskra算法。关键是求相同最短路径的个数以及最大的点权重之和。

代码:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>using namespace std;//此代码使用前,需删除下面两行+后面的system("PAUSE")
ifstream fin("in.txt");
#define cin finconst int CITYNUM = 500;
const int INF = 0x7fffffff;int city[CITYNUM];			//记录各个城市的团队数
int road[CITYNUM][CITYNUM]={0};
bool visited[CITYNUM]={false};
int minLen[CITYNUM]={0};	//从源城市到达index城市的最短路径值
int sum[CITYNUM]={0};		//从源城市到达index城市,所能召集的最大团队数
int same[CITYNUM]={0};		//从源城市到达index城市,具有相同最短的路径个数void Dij(int source,int dest,int n){		//dijkstra算法int i,t,mm,next;int count = 0;int cur = source;sum[cur]=city[cur];while(count< n-1){visited[cur]=true;mm=INF;for(i=0;i<n;i++){if(visited[i])continue;if(road[cur][i]){t = minLen[cur] + road[cur][i];if(t < minLen[i] || minLen[i]==0){		//到达城市i,出现新的最短路径minLen[i]=t;same[i]=1;						//重新计数sum[i]=sum[cur]+city[i];}else if(t == minLen[i]){			//到达城市i,出现相同的最短路径same[i]++;if(sum[cur]+city[i] > sum[i])	//记下团队数较大的值sum[i]=sum[cur]+city[i];}}if(minLen[i] < mm && minLen[i]!=0){mm = minLen[i];next = i;}}minLen[cur] = mm;if(next == dest)break;cur = next;count++;}return;
}int main()
{int n,m,sc,dc;cin>>n>>m>>sc>>dc;int i;for(i=0;i<n;i++)cin>>city[i];int c1,c2;for(i=0;i<m;i++){cin>>c1>>c2;cin>>road[c1][c2];road[c2][c1]=road[c1][c2];}if(sc==dc){							//若所在地就是目的地 则直接输出结果cout<<1<<' '<<city[sc]<<endl;return 0;}Dij(sc,dc,n);cout<<same[dc]<<' '<<sum[dc]<<endl;system("PAUSE");return 0;
}

测试点

测试点 结果 用时(ms) 内存(kB) 得分/满分
0 答案正确 0 580 10/10
1 答案正确 0 710 3/3
2 答案错误 0 580 0/3
3 答案错误 0 1510 0/3
4 答案错误 0 1510 0/3
5 答案正确 0 1510 3/3

        喔,经过和室友们的讨论,很快发现了问题所在。如下图这个Case:


输入数据为:

4 5 0 3
1 4 1 2
0 1 1
0 2 2
0 3 4
1 2 1
2 3 2

2号city的最短路径个数是2个,在计算目标3号city时需要考虑进去。

修改后,可AC的代码:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>using namespace std;//此代码使用前,需删除下面两行+后面的system("PAUSE")
ifstream fin("in.txt");
#define cin finconst int CITYNUM = 500;
const int INF = 0x7fffffff;int city[CITYNUM];			//记录各个城市的团队数
int road[CITYNUM][CITYNUM]={0};
bool visited[CITYNUM]={false};
int minLen[CITYNUM]={0};	//从源城市到达index城市的最短路径值
int sum[CITYNUM]={0};		//从源城市到达index城市,所能召集的最大团队数
int same[CITYNUM]={0};		//从源城市到达index城市,具有相同最短的路径个数void Dij(int source,int dest,int n){		//dijkstra算法int i,t,mm,next;int count = 0;int cur = source;sum[cur]=city[cur];same[cur]=1;while(count< n-1){visited[cur]=true;mm=INF;for(i=0;i<n;i++){if(visited[i])continue;if(road[cur][i]){t = minLen[cur] + road[cur][i];if(t < minLen[i] || minLen[i]==0){		//到达城市i,出现新的最短路径minLen[i]=t;same[i]=same[cur];			//重新计数,可能到达本节点cur的最短路径有多条sum[i]=sum[cur]+city[i];}else if(t == minLen[i]){			//到达城市i,出现相同的最短路径same[i]+=same[cur];if(sum[cur]+city[i] > sum[i])	//记下团队数较大的值sum[i]=sum[cur]+city[i];}}if(minLen[i] < mm && minLen[i]!=0){mm = minLen[i];next = i;}}minLen[cur] = mm;if(next == dest)break;cur = next;count++;}return;
}int main()
{int n,m,sc,dc;cin>>n>>m>>sc>>dc;int i;for(i=0;i<n;i++)cin>>city[i];int c1,c2;for(i=0;i<m;i++){cin>>c1>>c2;cin>>road[c1][c2];road[c2][c1]=road[c1][c2];}if(sc==dc){							//若所在地就是目的地 则直接输出结果cout<<1<<' '<<city[sc]<<endl;return 0;}Dij(sc,dc,n);cout<<same[dc]<<' '<<sum[dc]<<endl;system("PAUSE");return 0;
}

这篇关于【PAT 1003】 Emergency 图论Dijkstra的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877825

相关文章

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

uva 10801(乘电梯dijkstra)

题意: 给几个电梯,电梯0 ~ n-1分别可以到达很多层楼。 换乘电梯需要60s时间。 问从0层到target层最小的时间。 解析: 将进入第0层的电梯60s也算上,最后减。 坑点是如果target为0输出0。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algori

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

poj 3255 次短路(第k短路) A* + spfa 或 dijkstra

题意: 给一张无向图,求从1到n的次短路。 解析: A* + spfa 或者 dijkstra。 详解见上一题:http://blog.csdn.net/u013508213/article/details/46400189 本题,spfa中,stack超时,queue的效率最高,priority_queue次之。 代码: #include <iostream>#i

【代码随想录训练营第42期 续Day52打卡 - 图论Part3 - 卡码网 103. 水流问题 104. 建造最大岛屿

目录 一、做题心得 二、题目与题解 题目一:卡码网 103. 水流问题 题目链接 题解:DFS 题目二:卡码网 104. 建造最大岛屿 题目链接 题解:DFS  三、小结 一、做题心得 也是成功补上昨天的打卡了。 这里继续图论章节,还是选择使用 DFS 来解决这类搜索问题(单纯因为我更熟悉 DFS 一点),今天补卡的是水流问题和岛屿问题。个人感觉这一章节题对于刚

图论篇--代码随想录算法训练营第五十二天打卡| 101. 孤岛的总面积,102. 沉没孤岛,103. 水流问题,104.建造最大岛屿

101. 孤岛的总面积 题目链接:101. 孤岛的总面积 题目描述: 给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿指的是由水平或垂直方向上相邻的陆地单元格组成的区域,且完全被水域单元格包围。孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。 现在你需要计算所有孤岛的总面积,岛屿面积的计算方式为组成岛屿的陆地的总数。 解题思路: 从周边找到陆地,然后通过 dfs或者bfs 将

PAT甲级-1044 Shopping in Mars

题目   题目大意 一串项链上有n个钻石,输入给出每个钻石的价格。用m元买一个连续的项链子串(子串长度可为1),如果不能恰好花掉m元,就要找到最小的大于m的子串,如果有重复就输出多个,按递增顺序输出子串的前端和后端索引。 原来的思路 取连续的子串使和恰等于m,没有恰等于就找最小的大于。可以将子串依次累加,使得每个位置都是起始位置到该位置的序列和,整个数组显递增顺序,就可以用右边减左边

PAT (Advanced Level) Practice——1011,1012

1011:  链接: 1011 World Cup Betting - PAT (Advanced Level) Practice (pintia.cn) 题意及解题思路: 简单来说就是给你3行数字,每一行都是按照W,T,L的顺序给出相应的赔率。我们需要找到每一行的W,T,L当中最大的一个数,累乘的结果再乘以0.65,按照例子写出表达式即可。 同时还需要记录每一次选择的是W,T还是L

代码随想录 刷题记录-28 图论 (5)最短路径

一、dijkstra(朴素版)精讲 47. 参加科学大会 思路 本题就是求最短路,最短路是图论中的经典问题即:给出一个有向图,一个起点,一个终点,问起点到终点的最短路径。 接下来讲解最短路算法中的 dijkstra 算法。 dijkstra算法:在有权图(权值非负数)中求从起点到其他节点的最短路径算法。 需要注意两点: dijkstra 算法可以同时求 起点到所有节点的最短路径权值不

图论篇--代码随想录算法训练营第五十一天打卡| 99. 岛屿数量(深搜版),99. 岛屿数量(广搜版),100. 岛屿的最大面积

99. 岛屿数量(深搜版) 题目链接:99. 岛屿数量 题目描述: 给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。 解题思路: 1、每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 2、遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都