描述:
给N个定点N-1条边的无向连通图,且每条边的边权是1,现在从顶点1开始出发遍历完每个顶点,求最短的路程是多少?
样例:
input:
4
1 2
1 3
3 4
output :
4
解释: 从 1->2->1->3->4 路程一共是 4
思路:
N个顶点N-1条边的无向连通图就是树,且该树以顶点1为根。
那么从1开始遍历的话,如果遍历较短的分支,最后肯定得回到1的这个节点。所以我们把问题转化为,遍历所有的1的分支,且回到1需要多少路程,很显然,这个路程就是边数*2 也就是
(N−1)∗2
(
N
−
1
)
∗
2
,那么如何使得从顶点1出发,遍历完的路程最小呢? 很显然,也就是说顶点1的最长的那个分支只走一遍就行了(即树的高度 h)。最后结果就是
(N−1)∗2−h
(
N
−
1
)
∗
2
−
h
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <sstream>
#include <vector>
#include <map>
using namespace std;
const int maxn = 1e5+7;
const int INF = 1e9+7;
bool vis[maxn];
int dist[maxn];
vector<int>Edge[maxn];
int n;
int len = -1;
void dfs(int u)
{
vis[u] = 1;
len = max(len,dist[u]);
for (int i = 0; i < (int)Edge[u].size(); ++i) {
int v = Edge[u][i];
if (vis[v]) continue;
dist[v] = dist[u] + 1;
dfs(v);
}
}
void addE(int u,int v)
{
Edge[u].push_back(v);
Edge[v].push_back(u);
}
int main()
{
cin >> n;
int u,v;
for (int i = 0; i < n-1; ++i) {
cin >> u >> v;
addE(u,v);
}
dfs(1);
int res = 2*(n-1) - len;
cout << res << endl;
return 0;
}