AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识
链接: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 树的直径知识的更多相关文章
- [Atcoder Grand Contest 001] Tutorial
Link: AGC001 传送门 A: …… #include <bits/stdc++.h> using namespace std; ; ]; int main() { scanf(& ...
- AtCoder Grand Contest 001 D - Arrays and Palindrome
题目传送门:https://agc001.contest.atcoder.jp/tasks/agc001_d 题目大意: 现要求你构造两个序列\(a,b\),满足: \(a\)序列中数字总和为\(N\ ...
- Atcoder Grand Contest 001 F - Wide Swap(拓扑排序)
Atcoder 题面传送门 & 洛谷题面传送门 咦?鸽子 tzc 来补题解了?奇迹奇迹( 首先考虑什么样的排列可以得到.我们考虑 \(p\) 的逆排列 \(q\),那么每次操作的过程从逆排列的 ...
- AtCoder Grand Contest 001 题解
传送门 \(A\) 咕咕咕 const int N=505; int a[N],n,res; int main(){ scanf("%d",&n); fp(i,1,n< ...
- Atcoder Grand Contest 001 D - Arrays and Palindrome(构造)
Atcoder 题面传送门 洛谷题面传送门 又是道思维题,又是道把我搞自闭的题. 首先考虑对于固定的 \(a_1,a_2,\dots,a_n;b_1,b_2,\dots,b_m\) 怎样判定是否合法, ...
- JZOJ5405 & AtCoder Grand Contest 001 F. Permutation
题目大意 给出一个长度为\(n\)的排列\(P\)与一个正整数\(k\). 你需要进行如下操作任意次, 使得排列\(P\)的字典序尽量小. 对于两个满足\(|i-j|>=k\) 且\(|P_i- ...
- AtCoder Grand Contest 001
B - Mysterious Light 题意:从一个正三角形边上一点出发,遇到边和已走过的边则反弹,问最终路径长度 思路:GCD 数据爆long long #pragma comment(linke ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
- AtCoder Grand Contest 010
AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...
随机推荐
- C#中的文件操作
在.NET Framework 中进行的所有输入和输出工作都要用到流(stream) 有两种类型的流: 输出流:当向某些外部目标写入数据时,就要用到输出流(将数据写入到文件中). 输入流:用于将数据读 ...
- Oracle 6 - 锁
Oracle锁没有额外的开销?Oracle的锁是怎么实现的?因为其他数据库,锁都是一种稀有资源和开销. 答:代码级实现?? 没有锁的话,并发更新就会有丢失更新的问题. 悲观锁和乐观锁 悲观锁一般用于有 ...
- 深入浅出Java并发包—锁机制(三)
接上文<深入浅出Java并发包—锁机制(二)> 由锁衍生的下一个对象是条件变量,这个对象的存在很大程度上是为了解决Object.wait/notify/notifyAll难以使用的问题. ...
- linux入门教程(七) linux系统用户以及用户组管理
关于这部分内容,笔者在日常的linux系统管理工作中用到的并不多,但这并不代表该内容不重要.毕竟linux系统是一个多用户的系统,每个账号都干什么用,你必须了如指掌.因为这涉及到一个安全的问题. [认 ...
- CF 221div2 A. Lever
A. Lever 题目:http://codeforces.com/contest/376/problem/A 题意:杠杆原理 比两边的重量 input =^== output balance 9== ...
- 欧拉工程第68题:Magic 5-gon ring
题目链接 任意一条线上的三个数的和都等于9,顺时针,从最小的外圈开始,得到的序列是:432621213 和 序列 9位的字符串:三角环所能形成的最大字符串为432621513. ...
- lintcode:Remove Nth Node From End of Lis 删除链表中倒数第n个节点
题目: 删除链表中倒数第n个节点 给定一个链表,删除链表中倒数第n个节点,返回链表的头节点. 样例 给出链表1->2->3->4->5->null和 n = 2. 删除 ...
- 2014-9-17二班----9 web project
http://localhost:8080/rwkj1/indexServlet 跳转 http://localhost:8080/rwk ...
- QTableWidget嵌入QpushButton后定位是哪一个QpushButton
问题: 有时候会遇到这样的情况,在QTableWidget中我们需要嵌入一个QpushButton按钮,但是如何确定是哪个Button按下的呢? 解决: 一般地,一个按钮按下后会连接到一槽函数,那么在 ...
- mysqldump常用于MySQL数据库逻辑备份
mysqldump常用于MySQL数据库逻辑备份. 1.各种用法说明 A. 最简单的用法: mysqldump -uroot -pPassword [database name] > [dump ...