题目:

Problem Statement

Given an undirected tree, let the distance between vertices \(u\) and \(v\) be the number of edges on the simple path from \(u\) to \(v\). The diameter of a tree is the maximum among the distances between any two vertices. We will call a tree good if and only if its diameter is at most \(K\).

You are given an undirected tree with \(N\) vertices numbered \(1\) through \(N\). For each \(i(1\leq i\leq N−1)\), there is an edge connecting vertices \(A_i\) and \(B_i\).

You want to remove zero or more vertices from the tree, so that the resulting tree is good. When a vertex is removed, all incident edges will also be removed. The resulting graph must be connected.

Find the minimum number of vertices that you need to remove in order to produce a good tree.

Constraints

  • \(2\leq N\leq 2000\)
  • \(1\leq K\leq N−1\)
  • \(1\leq A_i \leq N,1\leq B_i \leq N\)
  • The graph defined by \(A_i\) and \(B_i\) is a tree.

题解

比较简单的一道题。

考虑如果以某一点为根,那么就是删去一定深度以上的节点。

稍微分析一下可以发现这样做一定会找到最优方案。

所以可以对所有的方案取\(min\)

那么下面的问题就是删除深度大于哪个值的节点。

对于给定的\(K\)是偶数的情况,那么直接删除深度大于\(\frac{K}{2}\)的所有点即可。

如果是奇数呢?

这时候我们转换思维,不枚举以哪一个点为根了,枚举以哪条边为根。

这时候我们可以发现接下来也只要删除所有深度大于\(\frac{K-1}{2}\)的点即可.

复杂度\(O(n^2)\)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 2048;
struct Edge{
int to,next;
}G[maxn<<1];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
#define v G[i].to
int dep[maxn];
void dfs(int u,int f){
for(rg i = head[u];i;i=G[i].next){
if(v == f) continue;
dep[v] = dep[u] + 1;
dfs(v,u);
}
}
#undef v
struct Node{
int u,v;
}e[maxn];
int main(){
int n,K;read(n);read(K);
int u,v;
rep(i,2,n){
read(u);read(v);
e[i].u = u;e[i].v = v;
add(u,v);add(v,u);
}
int ans = 0x3f3f3f3f;
if((K&1) == 0){
int res = 0;
rep(i,1,n){
res = dep[i] = 0;dfs(i,i);
rep(j,1,n) if(dep[j] > (K >> 1)) ++ res;
ans = min(ans,res);
}
}else{
int res = 0;
rep(i,2,n){
dep[e[i].u] = dep[e[i].v] = res = 0;
dfs(e[i].u,e[i].v);dfs(e[i].v,e[i].u);
rep(j,1,n){
if(dep[j] > (K >> 1)) ++ res;
}ans = min(ans,res);
}
}printf("%d\n",ans);
return 0;
}

ACC 001 C - Shorten Diameter 图论的更多相关文章

  1. AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识

    链接:http://agc001.contest.atcoder.jp/tasks/agc001_c 题解(官方): We use the following well-known fact abou ...

  2. Shorten Diameter

    Shorten Diameter Time limit : 2sec / Stack limit : 256MB / Memory limit : 256MB Score : 600 points P ...

  3. AGC001 C - Shorten Diameter【枚举】

    一开始没看到要保证最后是树--所以一定要从叶子开始删 枚举重心,如果k是偶数,那么按当前重心提起来deep大于k/2的全都要切掉,这样枚举重心然后取min即可 奇数的话就是枚举直径中间的边,然后从两边 ...

  4. AtCoderACGC001C Shorten Diameter

    Description: 给定一个\(n\)个点的树,要求删去最少的点使树的致直径不超过k Solution: 如果\(k\)为偶数,对于最终状态一定是以每一个点为根任何点的深度不能超过\(k/2\) ...

  5. AtCoder Grand Contest

    一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...

  6. RE:从零开始的AGC被虐(到)生活(不能自理)

    RE:从零开始的AGC被虐(到)生活(不能自理) 「一直注视着你,似近似远,总是触碰不到.」 --来自风平浪静的明天 AtCoder Grand Contest 001 B: Mysterious L ...

  7. A*G#C001

    AGC001 A BBQ Easy 贪心. https://agc001.contest.atcoder.jp/submissions/7856034 B Mysterious Light 很nb这个 ...

  8. 【AtCoder】AGC001

    AGC001 A - BBQ Easy 从第\(2n - 1\)个隔一个加一下加到1即可 #include <bits/stdc++.h> #define fi first #define ...

  9. AGC001[BCDE] 题解

    A没意思 F太难 所以大概近期的AGC题解都是BCDE的 然后特殊情况再说 开始刷AGC的原因就是计数太差 没有脑子 好几个学长都推荐的AGC所以就开始刷了 = = 大概两天三篇的速度?[可能也就最开 ...

随机推荐

  1. 区块链入门级别认知(blockchain)

    区块链入门级别认知(blockchain) 前言:今天参加了迅雷关于区块链的大会,学习和感受总结一下 之前的认知在:几个混迹互联网圈关于区块链 耳熟能详的 热词 “比特币” “区块链” “挖矿” ,知 ...

  2. 【LeetCode】【矩阵旋转】Rotate Image

    描述 You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise ...

  3. 【HackerRank】Find the Median(Partition找到数组中位数)

    In the Quicksort challenges, you sorted an entire array. Sometimes, you just need specific informati ...

  4. 给嵌入式linux串口添加密码的一些总结

    要添加串口登录密码就需要修改 /etc/inittab 文件的配置 但是不同的开发板情况不一样,有的是没有这个文件的,BusyBox会检查/etc/inittab文件是否存在, 如果此文件不存在, B ...

  5. Shell编程之Linux信号及信号跟踪

    一.Linux信号 1.什么是信号? Linux信号是由一个整数构成的异步消息,它可以由某个进程发给其他进程,也可以在用户按下特定键发生某种异常事件时,由系统发给某个进程. 2.信号列表 [root@ ...

  6. Eclipse常用快捷键(转帖)

    Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+ ...

  7. oracle 序列改值

    1.oracle 序列改值 执行:Alter Sequence SQ_RM_FRAME Increment By 100; 执行:Select SQ_RM_FRAME.NextVal From Dua ...

  8. 如何在java中导入jar包

    通常在lib文件夹中存放从外部引入的jar包 所以在项目上右击,new 一个folder,命名为lib 然后把JAR文件复制进去. 然后再在项目上右击,build Path ——configure b ...

  9. C# XML对象序列化、反序列化 - PEPE YU

    http://www.tuicool.com/articles/IjE7ban http://www.cnblogs.com/johnsmith/archive/2012/12/03/2799795. ...

  10. 阅读linux内核代码的工具-- Source Insight

    http://blog.csdn.net/luckyaslan/article/details/7869235 Step 1:安装Source Insight并启动程序 可以进入图1界面,在工具条上有 ...