终于回到亲爱的家

把屋里检查了几遍,确认所有东西都在包里了。才坐了下来等待离开。mm抱着我不说话。
next和afei来送我,帮忙拿了些东西,送上了的士。去西站的路上堵的厉害,差点没有赶上。连拽带跑才在最后几分中赶上k49。 只来得及在车外与mm简短的拥抱。
直到看不见了mm的身影,才没有出息的哭了。本来一段时间气氛还不算伤感,毕竟是回家了。只是一时场景所致。在车上给所有北京的朋友发了短信道别。从此就离开了这个生活了4年的城市。没有想到,刚刚熟悉,就要分别。

一路行程还算愉快。同车的基本是北京人去宜昌旅游的。一个隔间里有一个大三学生,也是一中的,学建筑;还有两位阿姨,一个在当代,一个在物美-_-b(当然,是别的点)。老一点的的阿姨比较有生活经历,基本上在听她教诲。第二天的早晨我还碰到两个初中小mm,给她们解答物理问题,浮在水面上的船平均密度到底怎么算……

k49晚点一个多小时,总算是到达了我亲爱的家乡,还有接我来的亲爱的爸爸妈妈。家乡的一切都变化缓慢,沿着熟悉的道路回家,基本不需要适应。刚进屋就开始下雨。下午晚上分别拜访了爷爷奶奶和外婆两家,吃到了久违的西坝口味……刚下火车就给我下这么重的药,受不了哇。
这个问题是一个图论中的选址问题,目标是在给定的 `n` 个居民点中选择两个点作为银行的位置,使得所有居民点到最近的银行的最短距离之和最小。 为了解决这个问题,我们可以按照以下步骤进行: --- ### **解决思路:** 1. **图的表示:** - 假设居民点之间通过图连接,每个居民点是图中的一个节点,居民点之间的道路是图中的边,边有权重表示距离。 - 使用邻接矩阵或邻接表来表示图。 2. **计算所有节点之间的最短距离:** - 使用 Floyd-Warshall 算法计算出所有节点之间的最短路径,时间复杂度为 O(n³),适用于小规模图(n ≤ 100)。 - 如果图较大,可以使用 Dijkstra 算法对每个节点做一次单源最短路径,时间复杂度为 O(n * (n + m)logn)。 3. **枚举两个银行的位置:** - 遍历所有可能的银行组合 `(i, j)`,其中 `i < j`。 - 对于每个组合,计算每个节点 `k` 到 `i` 和 `j` 的最小距离,然后累加得到总距离。 4. **找出最优组合:** - 找出所有组合中总距离最小的一组 `(i, j)`。 --- ### **C++ 实现代码(使用 Floyd-Warshall 算法)** ```cpp #include <iostream> #include <vector> #include <climits> using namespace std; const int INF = INT_MAX / 2; // 防止溢出 int main() { int n, m; cin >> n >> m; vector<vector<int>> dist(n, vector<int>(n, INF)); for (int i = 0; i < n; ++i) dist[i][i] = 0; for (int i = 0; i < m; ++i) { int u, v, w; cin >> u >> v >> w; u--; v--; // 转换为 0-based index dist[u][v] = dist[v][u] = w; } // Floyd-Warshall 算法计算所有点对之间的最短距离 for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (dist[i][k] + dist[k][j] < dist[i][j]) dist[i][j] = dist[i][k] + dist[k][j]; // 枚举两个银行的位置 int min_total = INF; pair<int, int> best_pair; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { int total = 0; for (int k = 0; k < n; ++k) { total += min(dist[k][i], dist[k][j]); // 每个点到最近银行的距离 } if (total < min_total) { min_total = total; best_pair = {i, j}; } } } cout << "最优银行设置在点 " << best_pair.first + 1 << " 和 " << best_pair.second + 1 << endl; cout << "最小总距离为: " << min_total << endl; return 0; } ``` --- ### **解释:** 1. **输入格式:** - 第一行输入两个整数 `n`(居民点个数)和 `m`(边的条数)。 - 接下来 `m` 行,每行三个整数 `u, v, w`,表示从居民点 `u` 到 `v` 有一条权值为 `w` 的边。 2. **Floyd-Warshall 算法:** - 用于计算所有点对之间的最短路径。 - 时间复杂度较高,但实现简单,适用于小图。 3. **枚举银行组合:** - 对于每对 `(i, j)`,计算每个点 `k` 到 `i` 或 `j` 的最短距离,并累加。 - 找出总距离最小的组合。 --- ### **优化建议:** - 如果图是稀疏图,建议使用 Dijkstra 算法代替 Floyd-Warshall。 - 如果 `n` 很大(比如超过 1000),则需要更高效的算法,例如启发式搜索(如 A*)或近似算法。 --- ###
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值