luogu3629 [APIO2010]巡逻
创造一个环出来,可以让环上的边都只访问一次。
对于 \(k=1\),答案就是树的直径两边连起来。
倘若 \(k=2\),那就先按照 \(k=1\) 的求一遍,然后我们发现,如果第二条加的边构成的环和第一条加的边构成的环有交,那么交必定会被访问两次。这样交不但没有减少访问次数,还抵消了第一次的成果。因此把第一次求出来的直径上的边权值由 \(1\) 变成 \(-1\) 再求一遍。
#include <iostream>
#include <cstdio>
using namespace std;
int n, k, uu, vv, hea[100005], cnt, len, zui[100005], cii[100005], zu=0;
const int oo=0x3f3f3f3f;
struct Edge{
int too, nxt, val;
}edge[200005];
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
edge[cnt].val = 1;
hea[fro] = cnt;
}
int dfs(int x, int f){
int maxi1=0, maxi2=0, qwq=0;
cii[x] = zui[x] = 0;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f){
int tmp=dfs(t, x)+edge[i].val;
if(tmp>maxi1){
maxi2 = maxi1;
maxi1 = tmp;
cii[x] = zui[x];
zui[x] = i;
}
else if(tmp>maxi2){
maxi2 = tmp;
cii[x] = i;
}
}
}
if(maxi1+maxi2>len){
len = maxi1+maxi2;
zu = x;
}
return maxi1;
}
void debug(int x, int f){
if(zui[x]){
edge[zui[x]].val = -1;
debug(edge[zui[x]].too, x);
}
if(cii[x]){
edge[cii[x]].val = -1;
debug(edge[cii[x]].too, x);
}
}
int main(){
cin>>n>>k;
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
len = 0;
dfs(1, 0);
int ans=2*(n-1)-(len-1);
if(k==2){
for(int i=zui[zu]; i; i=zui[edge[i].too])
edge[i].val = edge[((i-1)^1)+1].val = -1;
for(int i=cii[zu]; i; i=zui[edge[i].too])
edge[i].val = edge[((i-1)^1)+1].val = -1;
len = 0;
dfs(1, 0);
ans = ans - (len - 1);
}
cout<<ans<<endl;
return 0;
}
luogu3629 [APIO2010]巡逻的更多相关文章
- 洛谷 P3629 [APIO2010]巡逻 解题报告
P3629 [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通 ...
- [洛谷P3629] [APIO2010]巡逻
洛谷题目链接:[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以 ...
- [APIO2010]巡逻(树的直径)
[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到 ...
- [Apio2010] 巡逻
Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...
- P3629 [APIO2010]巡逻
题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任一个村庄.每条道 ...
- 树的直径【p3629】[APIO2010]巡逻
Description 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任一 ...
- 洛谷 P3629 [APIO2010]巡逻
题目在这里 这是一个紫题,当然很难. 我们往简单的想,不建立新的道路时,从1号节点出发,把整棵树上的每条边遍历至少一次,再回到1号节点,会恰好经过每条边两次,路线总长度为$2(n-1)$,根据树的深度 ...
- 【题解】P3629 [APIO2010]巡逻
link 题意 有 \(n\) 个村庄,编号为 \(1, 2, ..., n\) .有 \(n – 1\) 条道路连接着这些村 庄,从任何一个村庄都可以到达其他任一个村庄.道路长度均为 1. 巡警车每 ...
- BZOJ1912或洛谷3629 [APIO2010]巡逻
一道树的直径 BZOJ原题链接 洛谷原题链接 显然在原图上路线的总长为\(2(n-1)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...
随机推荐
- Problem D. What a Beautiful Lake dp
Problem D. What a Beautiful Lake Description Weiming Lake, also named "Un-named Lake", is ...
- python_18(Django基础)
第1章 web框架的本质 1.1 socket 1.2 空格后面是主体内容 1.3 HTTP协议 1.3.1 响应流程 1.4 HTTP请求方法 1.5 HTTP工作原理 1.6 URL 1.7 HT ...
- 20170308web作业1
代码20170308001: <%@ page language="java" import="java.util.*" pageEncoding=&qu ...
- 学习cocos2dx3.1.0
static_cast<type-id>expression 该运算符把expression转换为type-id类型 Lambda表达式 CallFunc::create([=](){} ...
- 双飞翼布局介绍-始于淘宝UED-2011年淘宝玉伯写的
仔细分析各种布局的技术实现,可以发现下面三种技术被经常使用: 浮动 float 负边距 negative margin 相对定位 relative position 这是实现布局的三个最基本的原子技术 ...
- ycsb安装和使用介绍
nosql性能测试工具ycsb0.1的使用 使用文档参考地址:https://www.cnblogs.com/SailorXiao/p/5808828.html ycsb地址:https://gith ...
- SQL 视图、事务
假设看多个不同的表 select *from student ,score,course,teacher 有重复的 改为select student.Sno,sname,ssex,sbirthd ...
- sql server Cannot resolve the collation conflict between "Chinese_PRC_BIN" and "Chinese_PRC_CI_AS" in the equal to operation
今天查询二个db,出现这个错误,二种方法,一种是把db里的collation改成一样的:如果不方便可以直接在sql语句后面转一下: select * from table where crm_mscr ...
- 洛谷 P1926 小书童——刷题大军
题目背景 数学是火,点亮物理的灯:物理是灯,照亮化学的路:化学是路,通向生物的坑:生物是坑,埋葬学理的人. 文言是火,点亮历史宫灯:历史是灯,照亮社会之路:社会是路,通向哲学大坑:哲学是坑,埋葬文科生 ...
- Codeforces Gym 100650B Countdown (离线)
题目链接:http://codeforces.com/gym/100650 根据给出的树和d,求出一些结点,这些结点形成子树的第d层结点数应该尽量多,具体要求可以参考题目. dfs一个结点前保存询问深 ...