• 21.10.17模拟 联络网 UVA11695弱化版


    给一棵树,求修改一条边后的最小树的直径

    考虑去掉一条边,形成两个子树,这两个子树怎么连边呢,肯定是子树的半径了
    新的树的直径要么是两颗子树的直径的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;
    }
    

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15419261.html

  • 相关阅读:
    Java Leetcode 两数之和
    Springboot 实现前后分离的固定响应结构 {code,data,msg} 代码及想法
    Java 通过原子类 AtomicStampedReference 实现自旋锁
    【待整理】PC端
    【Python】自动发送邮件
    【Python】调用C/C++ SDK/SO动态库
    【Python】整个项目所需的依赖包列表打包/项目迁移
    【待整理】工具
    【数据库】+Navicat 过期/14天试用期满
    【待整理】【后端】
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15419261.html
Copyright © 2020-2023  润新知