PAT 1003. Emergency (25) dij+增加点权数组和最短路径个数数组

2024-02-24 17:59

本文主要是介绍PAT 1003. Emergency (25) dij+增加点权数组和最短路径个数数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1003. Emergency (25)

时间限制
400 ms
内存限制
65536 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

仔细读题,最后需要输出的是最短路径中能够派出急救队数目和最大的数值

源代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <string>
 5 #include <cstring>
 6 #include <vector>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 const int maxn = 510;
11 const int INF = 0x3f3f3f3f;
12 int n,m,st,ed,G[maxn][maxn],weight[maxn];
13 int d[maxn],w[maxn],num[maxn];
14 bool vis[maxn]={false};
15 
16 void dij(int s) {
17     fill(d,d+maxn,INF);
18     memset(num,0,sizeof(num));
19     memset(w,0,sizeof(w));
20     d[s]=0;
21     w[s]=weight[s];
22     num[s]=1;
23     for(int i=0;i<n;++i) {
24         int u=-1,MIN=INF;
25         for(int j=0;j<n;++j) {
26             if(vis[j]==false&&d[j]<MIN) {
27                 u=j;
28                 MIN=d[j];
29             }
30         }
31         if(u==-1) return;
32         vis[u]=true;
33         for(int v=0;v<n;++v) {
34             if(vis[v]==false&&G[u][v]!=INF) {
35                 if(d[u]+G[u][v]<d[v]) {
36                     d[v]=d[u]+G[u][v];
37                     w[v]=w[u]+weight[v];
38                     num[v]=num[u];
39                 } else if(d[u]+G[u][v]==d[v]) {
40                     if(w[u]+weight[v]>w[v]) {
41                         w[v]=w[u]+weight[v];
42                     }
43                     num[v]+=num[u];
44                 }
45             }
46         }
47     }
48 }
49 int main() {
50     scanf("%d%d%d%d",&n,&m,&st,&ed);
51     for(int i=0;i<n;++i) {
52         scanf("%d",&weight[i]);
53     }
54     int u,v;
55     fill(G[0],G[0]+maxn*maxn,INF);
56     for(int i=0;i<m;++i) {
57         scanf("%d%d",&u,&v);
58         scanf("%d",&G[u][v]);
59         G[v][u]=G[u][v];
60     }
61     dij(st);
62     printf("%d %d\n",num[ed],w[ed]);
63     return 0;
64 }
View Code

 

转载于:https://www.cnblogs.com/lemonbiscuit/p/7775967.html

这篇关于PAT 1003. Emergency (25) dij+增加点权数组和最短路径个数数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

XTU 1233 n个硬币连续m个正面个数(dp)

题面: Coins Problem Description: Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face o

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop