链接:http://agc001.contest.atcoder.jp/tasks/agc001_c

题解(官方):

We use the following well-known fact about trees.
Let T be a tree, and let D be the diameter of the tree.

• If D is even, there exists an vertex v of T such that for each vertex w in
T, the distance between w and v is at most D/2.

• If D is odd, there exists an edge e of T such that for each vertex w in T,
the distance between w and one of the endpoints of e is at most (D −1)/2.
Here v and e are called centers of the tree.

The proof of this fact is not very hard. See the picture below. The blue
vertices are the endpoints of the diameters, and the red vertex (or edge) is in
the middle of the diameter. This red vertex is the center of the tree; if there
is a vertex v such that dist(v, red) > D/2, the distance between v and one of
blue points will be more than D (because the distance between the red point
and each blue point is D/2). The proof for odd case is similar.

Now the problem can be solved in the following way (we only describe the
solution for the even case, but the odd case is similar). Choose a vertex x in
the tree (this will be the center after removal of vertices) and count the number
of vertices y such that dist(x, y) > D/2. If we remove all such y, the diameter
of the remaining graph will be at most D. Thus, we can try all N vertices as x
and the answer is the minimum count of such y. The solution works in O(N^2).

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 2e3+;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9+;
typedef pair<int ,int >pii;
struct Edge{
int v,next;
}edge[N<<];
int head[N],tot,n,k;
void add(int u,int v){
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
bool vis[N];
int d[N];
void bfs(int s,int f){
queue<int>q;
while(!q.empty())q.pop();
d[s]=;vis[s]=true;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i = head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(vis[v]||v==f)continue;
d[v]=d[u]+;
vis[v]=true;
q.push(v);
}
}
}
int solveodd(int u,int v){
memset(d,INF,sizeof(d));
memset(vis,,sizeof(vis));
bfs(u,v);bfs(v,u);
int ret=;
for(int i=;i<=n;++i)
if(d[i]>k)++ret;
return ret;
}
int solveeven(int u){
memset(d,INF,sizeof(d));
memset(vis,,sizeof(vis));
bfs(u,);
int ret=;
for(int i=;i<=n;++i)
if(d[i]>k)++ret;
return ret;
}
int main(){
scanf("%d%d",&n,&k);
memset(head,-,sizeof(head));
for(int i=;i<=n-;++i){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
int ret=INF;
if(k&){
k>>=;
for(int i=;i<tot;i+=)
ret=min(ret,solveodd(edge[i].v,edge[i+].v));
}
else{
k>>=;
for(int i=;i<=n;++i)
ret=min(ret,solveeven(i));
}
printf("%d\n",ret);
return ;
}

AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识的更多相关文章

  1. [Atcoder Grand Contest 001] Tutorial

    Link: AGC001 传送门 A: …… #include <bits/stdc++.h> using namespace std; ; ]; int main() { scanf(& ...

  2. AtCoder Grand Contest 001 D - Arrays and Palindrome

    题目传送门:https://agc001.contest.atcoder.jp/tasks/agc001_d 题目大意: 现要求你构造两个序列\(a,b\),满足: \(a\)序列中数字总和为\(N\ ...

  3. Atcoder Grand Contest 001 F - Wide Swap(拓扑排序)

    Atcoder 题面传送门 & 洛谷题面传送门 咦?鸽子 tzc 来补题解了?奇迹奇迹( 首先考虑什么样的排列可以得到.我们考虑 \(p\) 的逆排列 \(q\),那么每次操作的过程从逆排列的 ...

  4. AtCoder Grand Contest 001 题解

    传送门 \(A\) 咕咕咕 const int N=505; int a[N],n,res; int main(){ scanf("%d",&n); fp(i,1,n< ...

  5. Atcoder Grand Contest 001 D - Arrays and Palindrome(构造)

    Atcoder 题面传送门 洛谷题面传送门 又是道思维题,又是道把我搞自闭的题. 首先考虑对于固定的 \(a_1,a_2,\dots,a_n;b_1,b_2,\dots,b_m\) 怎样判定是否合法, ...

  6. JZOJ5405 & AtCoder Grand Contest 001 F. Permutation

    题目大意 给出一个长度为\(n\)的排列\(P\)与一个正整数\(k\). 你需要进行如下操作任意次, 使得排列\(P\)的字典序尽量小. 对于两个满足\(|i-j|>=k\) 且\(|P_i- ...

  7. AtCoder Grand Contest 001

    B - Mysterious Light 题意:从一个正三角形边上一点出发,遇到边和已走过的边则反弹,问最终路径长度 思路:GCD 数据爆long long #pragma comment(linke ...

  8. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  9. AtCoder Grand Contest 010

    AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...

随机推荐

  1. ios开发图片点击放大

    图片点击放大,再次点击返回原视图.完美封装,一个类一句代码即可调用.IOS完美实现 创建了一个专门用于放大图片的类,以下为.h文件 #import <Foundation/Foundation. ...

  2. React事件处理函数的bind复用和name复用

    一.bind复用 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&qu ...

  3. ArcGIS 10.1 for Desktop新特性之地理标记照片

    转自:http://blog.csdn.net/esrichinacd/article/details/7730825 地理标记照片是指带有地理位置信息的照片,通常通过内置GPS的数码相机或智能手机拍 ...

  4. iOS Objective-C对象模型及应用

    前言 原创文章,转载请注明出自唐巧的技术博客. 本文主要介绍Objective-C对象模型的实现细节,以及Objective-C语言对象模型中对isa swizzling和method swizzli ...

  5. 58. Length of Last Word

    题目: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return t ...

  6. Java API ——Collection集合类 & Iterator接口

    对象数组举例: 学生类: package itcast01; /** * Created by gao on 15-12-9. */ public class Student { private St ...

  7. 高难度(3)RenderScript

    RenderScript RenderScript is a framework for running computationally intensive tasks at high perform ...

  8. Cookie的具体使用之来存储对象

    1.创建一个新的cookie,并赋值. HttpCookie cookie;       cookie=new HttpCookie("user");       cookie.D ...

  9. Null-conditional Operators

    https://msdn.microsoft.com/en-us/library/dn986595.aspx x?.y – null conditional member access. Return ...

  10. bzoj1876: [SDOI2009]SuperGCD

    更相减损数. 上手就debug了3个小时,直接给我看哭了. 3个函数都写错了是什么感受? 乘2函数要从前往后乘,这样后面的数乘2进位以后不会干扰前面的数. 除2函数要从后往前除,这样前面的数借来的位不 ...