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)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...
随机推荐
- [已读]JavaScript模式
主要是介绍各种继承和设计模式.第一章是讲编程规范,然后里面讲到了使用new Function替代eval
- Spark Mllib里数据集如何取前M行(图文详解)
不多说,直接上干货! 见具体, Hadoop+Spark大数据巨量分析与机器学习整合开发实战的第13章 使用决策树二元分类算法来预测分类StumbleUpon数据集 见具体 Hadoop+Spark大 ...
- JAVA设计模式之观察者模式 - Observer
有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事.对象甚至在运行时可决定是否要继续被通知.有了观察者,你将会消息灵通. 介绍 观察者模式的定义: 在对象之间 ...
- vue从入门到开发--1-安装脚手架
一: 1.在文件目录下打开命令窗口(按住shift+右键[在此处打开命令窗口]或者直接ctrl+R打开命令窗口,利用cd选择到自己的文件目录) 2.$ npm install --global vue ...
- error c2243:"类型转换" 转换存在,但无法访问
今天在程序的中有一段class Quackable : QuackObservable,结果一直出现error c2243:"类型转换" 转换存在,但无法访问. 后来发现只要改成c ...
- Does Little'law really applicable to apply performance model now?
上次提到Little定律, 我也解释过它跟另外一个公式有一些内在的关系,但是其实我自己对LL在当前复杂架构系统中到底是怎么应用的也没有完整的想法,于是我在Linkedin上把这个问题抛了出来,没有想到 ...
- 用python格式化小说txt
下载了<无人生还>的txt版.传到手机,发现阅读器识别得不够好. 原文格式如下: 第一章 一 沃格雷夫法官先生新近离任退休,现在正在头等车厢的吸烟室里,倚角而坐,一 边喷着雪茄烟,一边兴致 ...
- codevs 爱改名的小融
都是三道水题 但我很难理解的是 string 能过 char 就WA 2967 题目描述 Description Wikioi上有个人叫小融,他喜欢改名. 他的名字都是英文,只要按顺序出现R,K,Y三 ...
- Python学习日志9月13日
昨天的学习日志没有写,乱忙了一整天,政治电脑. 好奇心重,想要给电脑装上传说中LInux操作系统,各种小问题折腾到半夜,今天又折腾到晚上才真正的装上系统. 可是装上系统后又发现各种的不好用.虽然界面比 ...
- leetcode 127 单词接龙
给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字母. 转换过程中的中 ...