传送门:https://nanti.jisuanke.com/t/44347
这个题目 是说添加一条边让形成的环最大,那么就可以求一条树上的最长链,也就是树的直径。
1 DFS+DP
2 两次DFS
#include <iostream>
#include <malloc.h>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#define IO \
ios::sync_with_stdio(false); \
// cin.tie(0); \
// cout.tie(0);
using namespace std;
typedef unsigned long long uLL;
typedef long long LL;
const int maxn = 1e5 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const double PI = 3.14159;
const double eps = 1e-8;
struct Edge
{
int before;
int to;
} e[maxn];
int k, ans, head[maxn];
void add(int u, int v)
{
e[k].before = head[u];
e[k].to = v;
head[u] = k++;
}
int DFS(int x, int fa)
{
int tmp, mx = 0, mx2 = 0; //最长链与次长链初始化为0,如果链为负数我们不如不要
for (int i = head[x]; i != -1; i = e[i].before)
{
int v = e[i].to;
if (v != fa)
{
tmp = DFS(v, x);
if (tmp > mx)
mx2 = mx, mx = tmp;
else if (tmp > mx2)
mx2 = tmp;
}
}
ans = max(ans, mx + mx2 + 1);
return mx + 1; //最长链可以继续上传更新答案,但最长链和次长链连接起来不能上传
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
IO;
int T, n, x, y;
cin >> T;
while (T--)
{
memset(head, -1, sizeof head);
k = 0;
cin >> n;
for (int i = 0; i < n - 1; i++)
{
cin >> x >> y;
add(x, y);
add(y, x);
}
ans = -inf;
DFS(1, 0);
cout << n - ans << endl;
}
return 0;
}