21.10.17模擬 聯絡網 UVA11695弱化版
阿新 • • 發佈:2021-10-18
給一棵樹,求修改一條邊後的最小樹的直徑
考慮去掉一條邊,形成兩個子樹,這兩個子樹怎麼連邊呢,肯定是子樹的半徑了
新的樹的直徑要麼是兩顆子樹的直徑的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<<"~~~~~~~~~~~~~"<<'\n'; 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, '\n'); return 0; }
本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15419261.html