题目描述:
一张地图上有n个城市,城市和城市之间有且只有一条道路相连:要么直接相连,要么通过其它城市中转相连(可中转一次或多次),城市与城市之间的道路都不会成环。
当切断通往某个城市 i 的所有道路后,地图上将分为多个连通的城市群,设该城市i的聚集度为DPi,DPi = max(城市群1的城市个数,城市群2的城市个数,…城市群m 的城市个数);
请找出地图上DP值最小的城市(即找到城市j,使得DPj = min(DP1,DP2 … DPn))
提示:
1. 如果有多个城市都满足条件,这些城市都要找出来(可能存在多个解)
2. DPi的计算,可以理解为已知一棵树,删除某个节点后;生成的多个子树,求解多个子数节点数的问题。
输入描述:
第一行有一个整数N,表示有N个节点,1 <= N <= 1000;
接下来的N-1行每行有两个整数x,y,表示城市x与城市y连接,
1 <= x, y <= N;
输出描述:
输出城市的编号,如果有多个,按照编号升序输出。
示例1:
输入
5
1 2
2 3
3 4
4 5
输出
3
说明:输入表示的是如下地图:1 - 2 -3 - 4 - 5
对于城市3,切断通往3的所有道路后,形成2个城市群[(1,2),(4,5)],其聚集度分别都是2,DP3=2;
对于城市4,切断通往4的所有道路后,形成2个城市群[(1,2,3),(5)],其聚集度DP4=max(3,1)=3;
依次类推,切断其他城市所有道理后,得到的DP都会大于2,因此城市3就是DP值最小的城市,输出3;
示例2:
输入
6
1 2
2 3
2 5
3 4
3 6
输出
2 3
说明:输入表示的是如下地图:
6
|
1 - 2 -3 - 4
|
5
对于城市2,切断通往2的所有道路后,形成3个城市群[(1),(5),(3,4,6)],其聚集度分别都是1,1,3,DP2=max(1,1,3)=3。
对于城市3,切断通往3的所有道路后,形成3个城市群[(1,2,5),(4),(6)],其聚集度DP3=max(3,1.1)=3。
依次类推,切断其他城市所有道理后,得到的DP都会大于3,因此城市2、3就是DP值最小的城市,升序排列输出是2 3;
C++源码:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
// 使用邻接表来存储每个城市与其相连的城市
unordered_map<int, vector<int>> linkCity;
vector<int> dp;
// 深度优先搜索,用于计算从城市u出发,不通过城市cutCity所能到达的城市数
int dfs(int u, int cutCity) {
int cityNum = 1; // 初始化当前城市计数为1
for (int v : linkCity[u]) {
if (v == cutCity) {
continue; // 避免回到上一个城市,即父节点
}
cityNum += dfs(v, u); // 递归计算子城市的总数,并累加
}
return cityNum; // 返回从当前城市出发的总城市数
}
void dpFind(const vector<pair<int, int>>& connections) {
int n = connections.size() + 1;
// 构建城市之间的连接关系
for (const auto& conn : connections) {
int u = conn.first;
int v = conn.second;
linkCity[u].push_back(v);
linkCity[v].push_back(u);
}
dp.resize(n + 1, 0); // 创建一个数组用来存储每个城市的聚集度
// 计算每个城市的聚集度
for (int i = 1; i <= n; ++i) {
for (int x : linkCity[i]) {
dp[i] = max(dp[i], dfs(x, i)); // 使用dfs函数来找出以该城市为根节点,断开后的最大连通城市数
}
}
// 找到最小的聚集度
int minval = *min_element(dp.begin() + 1, dp.end());
// 输出所有具有最小聚集度的城市编号
for (int i = 1; i <= n; ++i) {
if (dp[i] == minval) {
cout << i << " ";
}
}
cout << endl;
}
int main() {
int n;
cin >> n; // 读取城市数量
vector<pair<int, int>> connections(n - 1); // 存储城市间连接关系
// 读取城市之间的连接关系
for (auto& conn : connections) {
cin >> conn.first >> conn.second;
}
dpFind(connections);
system("pause");
return 0;
}