嗯。。。其实就直接dfs就可以了。。。
就是先枚举一条边砍掉 = =
然后呢先计算 u 和 v 的答案。。
然后再dfs一遍修正答案。。。。。
#include <cstdio>
#include <iostream>
using namespace std;
const int Nmax = 3e3 + 5;
int N;
struct ed{
int u, v, w, next;
}e[Nmax * 2];
int k = 1, head[Nmax];
inline void adde(int u, int v, int w)
{
e[k] = (ed) { u, v, w, head[u] };
head[u] = k++;
}
int pre(int u, int fa)
{
int res = 0;
for (int i = head[u]; i; i = e[i].next) {
if (e[i].v == fa) continue;
res += pre(e[i].v, u);
if (!e[i].w) ++ res;
}
return res;
}
int find(int u, int fa, int already)
{
int res = already;
for (int i = head[u]; i; i = e[i].next) {
if (e[i].v == fa) continue;
int next = already;
if (e[i].w) ++ next; else -- next;
res = min(res, find(e[i].v, u, next));
}
return res;
}
int main()
{
ios :: sync_with_stdio(false);
cin >> N; int u, v;
for (int i = 1; i < N; ++ i) {
cin >> u >> v;
adde(u, v, 1); adde(v, u, 0);
}
int ans = N - 1;
for (int i = 1; i < k; i += 2) {
int u = e[i].u, v = e[i].v;
int cnt1 = pre(u, v), cnt2 = pre(v, u);
//cout << cnt1 << " " << cnt2 << endl;
cnt1 = find(u, v, cnt1); cnt2 = find(v, u, cnt2);
//cout << cnt1 << " " << cnt2 << endl;
ans = min(ans, cnt1 + cnt2);
}
cout << ans << endl;
return 0;
}