zoukankan      html  css  js  c++  java
  • 【BZOJ】2237: [NCPC2009]Flight Planning

    题意

    (n(1 le n le 2500))个点的树,求删掉一条边再加上一条边使得还是一棵树,且任意两点最大距离最小。

    分析

    考虑枚举删掉每一条边,我们只需要考虑如何加边容易求得新树的最大距离。
    当然是直径的一半咯。

    题解

    枚举每一条边,然后求两个连通块的直径,然后最大距离(=max(len1, len2, (len1+1)/2+(len2+1)/2+1))

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2505;
    struct E {
    	int next, to;
    }e[N<<1];
    int ihead[N], d[N], cnt, clr, n;
    void add(int x, int y) {
    	e[++cnt]=(E){ihead[x], y}; ihead[x]=cnt;
    	e[++cnt]=(E){ihead[y], x}; ihead[y]=cnt;
    }
    void dfs(int x, int f) {
    	for(int i=ihead[x]; i; i=e[i].next) {
    		int y=e[i].to;
    		if(y==f || i==clr || i==clr-1) {
    			continue;
    		}
    		d[y]=d[x]+1;
    		dfs(y, x);
    	}
    }
    int getlen(int x) {
    	memset(d, 0, sizeof(int)*(n+1));
    	dfs(x, 0);
    	for(int i=1; i<=n; ++i) {
    		if(d[i]>d[x]) {
    			x=i;
    		}
    	}
    	memset(d, 0, sizeof(int)*(n+1));
    	dfs(x, 0);
    	for(int i=1; i<=n; ++i) {
    		if(d[i]>d[x]) {
    			x=i;
    		}
    	}
    	return d[x];
    }
    int x[N], y[N];
    int main() {
    	scanf("%d", &n);
    	for(int i=1; i<n; ++i) {
    		scanf("%d%d", &x[i], &y[i]);
    		add(x[i], y[i]);
    	}
    	int ans=n;
    	for(int i=1; i<n; ++i) {
    		clr=i*2;
    		int len1=getlen(x[i]), len2=getlen(y[i]), a=(len1+1)/2, c=(len2+1)/2;
    		ans=min(ans, max(a+c+1, max(len1, len2)));
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
  • 相关阅读:
    泛型类,泛型方法的使用
    Mapper注解与MapperScan注解
    Configuration注解
    LA 4254 Processor (二分 + 贪心)
    UVa 10382 Watering Grass (贪心 区间覆盖)
    UVA 10795 A Different Task (递归)
    LA 3401 Colored Cubes (搜索 + 暴力)
    uva11464 Even Parity (枚举+递推)
    icpc2021 昆明 K (dfs爆搜)
    hdu3533 (bfs + 模拟)
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985727.html
Copyright © 2011-2022 走看看