洛谷 P2935 [USACO09JAN] Best Spot S

文章目录

  • [USACO09JAN] 最佳牧场 S
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
  • 思路解析
  • CODE



[USACO09JAN] 最佳牧场 S

题目链接:https://www.luogu.com.cn/problem/P2935

题目描述

贝茜,总是希望优化她的生活,她发现自己真的很喜欢访问农夫约翰的P (1 <= P <= 500)个牧场中的F (1 <= F <= P)个她最喜欢的牧场F_i。

贝茜知道她可以通过C (1 <= C <= 8,000)条双向的牛道(方便地编号为1…C)来连接各个牧场,以便在整个农场的任何牧场之间旅行。每条路径P_i都有一个时间T_i (1 <= T_i <= 892)来穿越该路径(无论哪个方向)和两个路径端点a_i和b_i (1 <= a_i <= P; 1 <= b_i <= P)。

贝茜想找到最好的牧场来睡觉,这样当她醒来时,到达她的F个最喜欢的牧场的平均时间就最小了。

举例来说,考虑一个农场的布局如下图所示,其中*'d牧场编号是最喜欢的。括号中的数字是穿越牛道的时间。


            1*--[4]--2--[2]--3
                     |       |
                    [3]     [4]
                     |       |
                     4--[3]--5--[1]---6---[6]---7--[7]--8*
                     |       |        |         |
                    [3]     [2]      [1]       [3]
                     |       |        |         |
                    13*      9--[3]--10*--[1]--11*--[3]--12*

以下表格显示了牧场4、5、6、7、9、10、11和12的潜在’最佳位置’的距离:

      * * * * * * 最喜欢的 * * * * * *
 潜在的最佳      牧场     牧场     牧场     牧场     牧场     牧场     平均
牧场              1       8      10      11      12      13        距离
------------      --      --      --      --      --      --      -----------
    4              7      16       5       6       9       3      46/6 = 7.67
    5             10      13       2       3       6       6      40/6 = 6.67
    6             11      12       1       2       5       7      38/6 = 6.33
    7             16       7       4       3       6      12      48/6 = 8.00
    9             12      14       3       4       7       8      48/6 = 8.00
   10             12      11       0       1       4       8      36/6 = 6.00 ** 最佳
   11             13      10       1       0       3       9      36/6 = 6.00
   12             16      13       4       3       0      12      48/6 = 8.00

因此,假设这些选择是最好的(一个程序必须以某种方式检查所有的选择),最好的睡觉地点是牧场10。

约翰拥有P(1<=P<=500)个牧场.贝茜特别喜欢其中的F个.所有的牧场 由C(1 < C<=8000)条双向路连接,第i路连接着ai,bi,需要Ti(1<=Ti< 892)单 位时间来通过.

作为一只总想优化自己生活方式的奶牛,贝茜喜欢自己某一天醒来,到达所有那F个她喜欢的 牧场的平均需时最小.那她前一天应该睡在哪个牧场呢?请帮助贝茜找到这个最佳牧场.

此可见,牧场10到所有贝茜喜欢的牧场的平均距离最小,为最佳牧场.

输入格式

* 第1行:三个空格分隔的整数:P、F和C

* 第2行到F+1行:第i+2行包含一个整数:F_i

* 第F+2行到C+F+1行:第i+F+1行用三个空格分隔的整数描述牛道i:a_i、b_i和T_i

输出格式

* 第1行:一行,一个整数,表示最好的牧场在哪里睡觉。如果有多个牧场是最好的,选择最小的那个。

样例 #1

样例输入 #1

13 6 15 
11 
13 
10 
12 
8 
1 
2 4 3 
7 11 3 
10 11 1 
4 13 3 
9 10 3 
2 3 2 
3 5 4 
5 9 2 
6 7 6 
5 6 1 
1 2 4 
4 5 3 
11 12 3 
6 10 1 
7 8 7

样例输出 #1

10

提示

如题目所述

如题目所述。



思路解析

F l o y d Floyd Floyd 算法将多源最短路算出多源点的最短路距离,最后加起来比较即可。


CODE

#include 
#include 
#include 
#include 
#include 
#define ll long long
#define INF 0x3f3f3f3f 

using namespace std;

typedef pair<int, int> pii;

const int N = 520, M = 8010;
int d[N][N]; // 存储每个节点之间的最短距离
int n, m, k; // n是节点数,k是喜欢的节点数,m是边的数目
vector<int> love; // 存储喜欢的节点

// Floyd-Warshall算法,用于计算所有节点对之间的最短路径
void floyd(){
	for(int k = 1; k <= n; ++k)
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= n; ++j)
				d[i][j] = min(d[i][j], 
				(d[i][k] == INF || d[k][j] == INF) ? INF : d[i][k] + d[k][j]);
}

int main(){
	cin >> n >> k >> m; // 输入节点数,喜欢的节点数,边的数目
	
	// 初始化距离矩阵
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			d[i][j] = (i == j ? 0 : INF);
	
	// 输入喜欢的节点
	while(k--){
		int f;
		scanf("%d", &f);
		love.push_back(f); 
	}
	
	// 输入边的信息
	while(m--){
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		d[a][b] = d[b][a] = min(d[a][b], w);
	}
	
	// 计算所有节点对之间的最短路径
	floyd();
	
	int ans = 0, res = INF; // 初始化答案和最小平均距离
	// 遍历所有节点,找到平均距离最小的节点
	for(int i = 1; i <= n; ++i){
        int tmp = 0;
	    for(int j = 0; j < love.size(); ++j){
	        tmp += d[i][love[j]];
	    }
	    
	    if(res > tmp){
	        res = tmp;
	        ans = i;
	    }
	}
	
	cout << ans; // 输出结果
}

  • 唯一需要注意的点就是res要初始化成一个很大的数,不然会影响后续记录最小的点

你可能感兴趣的:(#,最短路,c++,算法,笔记)