创造一个环出来,可以让环上的边都只访问一次。

对于 \(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]巡逻的更多相关文章

  1. 洛谷 P3629 [APIO2010]巡逻 解题报告

    P3629 [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通 ...

  2. [洛谷P3629] [APIO2010]巡逻

    洛谷题目链接:[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以 ...

  3. [APIO2010]巡逻(树的直径)

    [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到 ...

  4. [Apio2010] 巡逻

    Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...

  5. P3629 [APIO2010]巡逻

    题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任一个村庄.每条道 ...

  6. 树的直径【p3629】[APIO2010]巡逻

    Description 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任一 ...

  7. 洛谷 P3629 [APIO2010]巡逻

    题目在这里 这是一个紫题,当然很难. 我们往简单的想,不建立新的道路时,从1号节点出发,把整棵树上的每条边遍历至少一次,再回到1号节点,会恰好经过每条边两次,路线总长度为$2(n-1)$,根据树的深度 ...

  8. 【题解】P3629 [APIO2010]巡逻

    link 题意 有 \(n\) 个村庄,编号为 \(1, 2, ..., n\) .有 \(n – 1\) 条道路连接着这些村 庄,从任何一个村庄都可以到达其他任一个村庄.道路长度均为 1. 巡警车每 ...

  9. BZOJ1912或洛谷3629 [APIO2010]巡逻

    一道树的直径 BZOJ原题链接 洛谷原题链接 显然在原图上路线的总长为\(2(n-1)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...

随机推荐

  1. Java反射 : Declared的作用 ( 例如 : getMethods和getDeclaredMethods )

    import com.tangcheng.learning.service.lock.annotation.KeyParam; import lombok.Data; import lombok.Eq ...

  2. jsp get与post请求乱码问题

    乱码问题01:<%reques.setCharacterEncoding("utf-8");%> 02:get请求乱码 001.:String 编码之后的字符串 = n ...

  3. C# 枚举类型的描述信息获取

    新建一个控制台方法,写好自己的枚举类型: 如图: 在里面添加获取描述的方法: 具体源码: 链接:http://pan.baidu.com/s/1nv4rGkp 密码:byz8

  4. netty-socketio即时通讯

    jar包和依赖包在360云盘中:所有文件 > 学习 > jar包 > netty-socketio-1.7.10以及依赖 原文链接:http://www.cnblogs.com/al ...

  5. 【转】HashMap,ArrayMap,SparseArray源码分析及性能对比

    HashMap,ArrayMap,SparseArray源码分析及性能对比 jjlanbupt 关注 2016.06.03 20:19* 字数 2165 阅读 7967评论 13喜欢 43 Array ...

  6. 在Window上用cmd创建.htaccess文件

    Windows 图形下不能直接建立空名字的文件,所以没法直接创建.htaccess文件,不过可以通过命令行创建: cd /path/to/your/dir/ type nul>.htaccess ...

  7. Android 两个ArrayList找出相同元素及单个ArrayList删除元素

    //从一个ArrayList中删除重复元素 List<String> arrayList1 = new ArrayList<String>(); arrayList1.add( ...

  8. POJ 2449 Remmarguts' Date

    Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30725   Accepted: 8389 Description &quo ...

  9. druid 配置WebStatFilter 网络统计以及监控

    WebStatFilter用于采集web-jdbc关联监控的数据. web.xml配置 <filter> <filter-name>DruidWebStatFilter< ...

  10. gdb插件使用方法

    0x00 peda peda 安装: git clone https://github.com/longld/peda.git ~/peda echo "source ~/peda/peda ...