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;
    }
  • 相关阅读:
    nginx日志格式字段
    set_include_path和get_include_path用法详解
    nginx try_files 详解
    ul ol li的序号编号样式
    PHP中报500错误时如何查看错误信息
    nginx的access.log文件详解
    一些常用服务命令和配置目录
    PHP 使用 Redis
    HTML5-indexedDB使用常见错误总结
    浏览器数据库 IndexedDB 入门
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985727.html
Copyright © 2011-2022 走看看