给一棵树,求修改一条边后的最小树的直径
考虑去掉一条边,形成两个子树,这两个子树怎么连边呢,肯定是子树的半径了
新的树的直径要么是两颗子树的直径的max,要么就是新边两个端点在所在子树为起点最长链的和+1,显然这个为起点最长链最小为子树的半径
考场只会n^2暴力。但是这题是远古题,可以过,luogu有个线性的,但是看不懂,待补
//uva11695
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i(j);i<=k;++i)
#define drp(i,j,k) for(int i(j);i>=k;--i)
#define repg(x) for(int i(G.head[x]);i;i=G.next[i])
#define bug cout<<"~~~~~~~~~~~~~"<<'
';
using std::cin;
using std::cout;
typedef long long lxl;
template<typename T>
inline T max( T a, T b) {
return a > b ? a : b;
}
template<typename T>
inline T min( T a, T b) {
return a < b ? a : b;
}
inline char gt() {
static char buf[1 << 21], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename T>
inline void read(T &x) {
register char ch = gt();
x = 0;
int w(0);
while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
w ? x = ~(x - 1) : x;
}
template <typename T>
inline void out(T x, char cc) {
if(x < 0) x = -x, putchar('-');
char ch[20];
int num(0);
while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
while(num) putchar(ch[num--]);
putchar(cc);
}
const int N = 3e3 + 79;
int a[N], b[N];
struct graph {
int head[N], tot, next[N << 1], ver[N << 1];
inline void add(int a, int b) {
ver[++tot] = b;
next[tot] = head[a];
head[a] = tot;
}
} G;
int el, er, farest;
int dis[N], pre[N];
std::vector<int> GG;
std::queue<int> q;
inline void bfs(int st) {
memset(dis, 0xff, sizeof dis);
pre[st] = -1;
dis[st] = 0;
q.push(st);
farest = st;
while(!q.empty()) {
int x = q.front();
q.pop();
repg(x) {
int y(G.ver[i]);
if(dis[y] != -1 || (min(x, y) == min(el, er) && max(x, y) == max(el, er)))continue;
dis[y] = dis[x] + 1;
pre[y] = x;
q.push(y);
if(dis[y] > dis[farest]) farest = y;
}
}
GG.clear();
int tmp = farest;
while(tmp != -1) {
GG.push_back(tmp);
tmp = pre[tmp];
}
}
int ans(1e9);
inline void solve() {
int t(1);
bfs(el);
bfs(farest);
t += (dis[farest] + 1) / 2;
int aa = dis[farest];
bfs(er);
bfs(farest);
t += (dis[farest] + 1) / 2;
ans = min(ans, max(aa, max(t, dis[farest])));
}
int n;
int main() {
freopen("network.in","r",stdin);
freopen("network.out","w",stdout);
read(n);
rep(i, 1, n - 1) {
read(a[i]);
read(b[i]);
G.add(a[i], b[i]);
G.add(b[i], a[i]);
}
rep(i, 1, n - 1) {
el = a[i];
er = b[i];
solve();
}
out(ans, '
');
return 0;
}