bzoj 1912: [Apio2010]patrol 巡逻
呵呵呵呵呵呵,自己画图,大概半个小时,觉的连上边会成环(是不是该交仙人掌了??)然后求环不重合部分最大就好了,
结果写了一坨DP,最后写不下去了,再次扒了题解。
发现我真的是个sb。
k==1,直接是直径
k==2,搞出直径然后把直径删掉(把权值赋为-1,再找直径)(有点像我一开始想的每次找个最长链去贪心,然而,,总觉得,这种题贪心这么可能对)
/*#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) x&(-x)
#define inf 0x3f3f3f3f
#define N 100005
using namespace std;
inline int ra()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int head[N],cnt,n,f[N][3][3],k;
struct edge{int next,to;}e[N<<1];
void insert(int x, int y){e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;}
void dfs(int x, int fa)
{
int mx1=0,mx2=0,mx3=0,mx4=0;
for (int i=head[x];i;i=e[i].next)
{
if (e[i].to==fa) continue;
dfs(e[i].to,x);
int orz=f[e[i].to][0][1],flag=1,hehe=1;
if (orz<=mx1 && orz<=mx2 && orz<=mx3 && orz>mx4) mx4=orz;
if (orz<=mx1 && orz<=mx2 && orz>mx3) mx4=mx3,mx3=orz;
if (orz<=mx1 && orz>mx2) mx4=mx3,mx3=mx2,mx2=orz,hehe=0;
if (orz>mx1) mx4=mx3,mx3=mx2,mx2=mx1,mx1=orz,flag=0;
if (f[x][1][1] && k)
{
if (!flag)
f[x][2][0]=max(f[x][2][0],f[x][1][1]+mx1+1);
else if (!hehe) f[x][2][0]=max(f[x][2][0],f[x][1][1]+mx2+1);
}
cout<<f[x][1][1]<<endl;
if (f[x][1][0] && k) f[x][1][1]=max(f[x][1][1],f[x][1][0]+mx1+1);
cout<<f[x][1][1]<<endl;
if (f[e[i].to][1][0] && mx2 && k) f[x][1][1]=max(f[x][1][1],1+f[e[i].to][1][0]+flag?mx1:mx2);
if (f[e[i].to][1][1] && k) f[x][1][1]=max(f[x][1][1],f[e[i].to][1][1]+1);
if (f[e[i].to][1][1] && mx2 && k) f[x][2][0]=max(f[x][2][0],1+f[e[i].to][1][1]+flag?mx1:mx2);
if (f[e[i].to][2][0] && k) f[x][2][0]=max(f[x][2][0],f[e[i].to][2][0]);
if (f[x][1][0] && f[e[i].to][1][0] && k) f[x][2][0]=max(f[x][2][0],f[x][1][0]+f[e[i].to][1][0]);
f[x][1][0]=max(f[x][1][0],max(mx1+mx2+1,f[e[i].to][1][0]));
f[x][0][1]=mx1+1;
if (f[3][1][1]==3) {cout<<x<<" "<<e[i].to; while (1);}
}
printf("%d %d %d %d %d\n",x,f[x][0][1],f[x][1][0],f[x][1][1],f[x][2][0]); system("pause");
}
int main(int argc, char const *argv[])
{
n=ra(); k=ra(); k--;
for (int i=1; i<n; i++)
{
int x=ra(),y=ra();
insert(x,y); insert(y,x);
}
dfs(1,0);
printf("%d\n",n*2-f[1][k+1][0]);
return 0;
}*/
#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) x&(-x)
#define inf 0x3f3f3f3f
#define N 100005
using namespace std;
inline int ra()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
int mx,n,k,tot,cnt=,len;
int head[N];
int s1[N],s2[N];
struct edge{
int to,next,v;
}e[N<<];
void insert(int x, int y){
e[++cnt].next=head[x]; e[cnt].to=y; e[cnt].v=; head[x]=cnt;
}
int dfs(int x, int fa)
{
int mx1=,mx2=;
for (int i=head[x];i;i=e[i].next)
{
if (e[i].to==fa) continue;
int v=e[i].v+dfs(e[i].to,x);
if (v>mx1) mx2=mx1,mx1=v,s2[x]=s1[x],s1[x]=i;
else if (v>mx2) mx2=v,s2[x]=i;
}
if (mx1+mx2>len) len=mx1+mx2,mx=x;
return mx1;
}
int main(int argc, char const *argv[])
{
n=ra(); k=ra(); tot=*(n-);
for (int i=; i<n; i++)
{
int x=ra(),y=ra();
insert(x,y);
insert(y,x);
}
dfs(,); tot-=len-;
if (k==)
{
len=;
for (int i=s1[mx];i;i=s1[e[i].to]) e[i].v=e[i^].v=-;
for (int i=s2[mx];i;i=s1[e[i].to]) e[i].v=e[i^].v=-;
dfs(,); tot-=len-;
}
cout<<tot;
return ;
}
bzoj 1912: [Apio2010]patrol 巡逻的更多相关文章
- BZOJ 1912: [Apio2010]patrol 巡逻 (树的直径)(详解)
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=1912 题解: 首先,显然当不加边的时候,遍历一棵树每条边都要经过两次.那么现在考虑k==1 ...
- bzoj 1912 : [Apio2010]patrol 巡逻 树的直径
题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #includ ...
- bzoj 1912: [Apio2010]patrol 巡逻【不是dp是枚举+堆】
我是智障系列.用了及其麻烦的方法= =其实树形sp就能解决 设直径长度+1为len(环长) 首先k=1,直接连直径两端就好,答案是2*n-len 然后对于k=2,正常人的做法是树形dp:先求直径,然后 ...
- 【BZOJ】1912: [Apio2010]patrol 巡逻(树的直径)
题目 传送门:QWQ 分析 $ k=1 $ 时显然就是树的直径 $ k=2 $ 时怎么做呢? 做法是把一开始树的直径上的边的边权改成$ -1 $,那么当我们第二次用这些边做环时就抵消了一开始的贡献. ...
- BZOJ 1912:[Apio2010]patrol 巡逻(树直径)
1912: [Apio2010]patrol 巡逻 Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ ...
- [Apio2010]patrol 巡逻
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2541 Solved: 1288[Submit][S ...
- 【BZOJ1912】[Apio2010]patrol 巡逻 树形DP
[BZOJ1912][Apio2010]patrol 巡逻 Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示 ...
- 【bzoj1912】 Apio2010—patrol 巡逻
http://www.lydsy.com/JudgeOnline/problem.php?id=1912 (题目链接) 题意 给出一棵树,要求在树上添加K(1 or 2)条边,添加的边必须经过一次,使 ...
- BZOJ1912 [Apio2010]patrol 巡逻
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
随机推荐
- 在Centos 7.7下用minikube部署单节点kubernetes.
centos8 下用yum安装docker-ce会报错,说明docker-ce对centos8支持还不太好.所以在centos7.7下安装 先更新一下系统 yum update 安装 yum工具, ...
- 定位(left 、right 、top 、 bottom)、padding、margin 值设为百分比值时
定位(left .right .top . bottom): top 为例 right 为例 padding.margin : 当padding.margin 值设为百分比值时,其百分比会相对于父元素 ...
- Centos7 更新配置为阿里源步骤
一.yum更换配置源过程 1.备份原有的.repo源文件 首先需要将之前的源进行备份(一般重要的配置文件都需要有备份的意识) # 进入源配置目录 cd /etc/yum.repos.d # 创建备份文 ...
- Xcode 9.0 报错,Safe Area Layout Guide Before IOS 9.0
解决方案就是: 第一步 第二步 第三步 重新编译.
- C++ STL vector容量(capacity)和大小(size)的区别
很多初学者分不清楚 vector 容器的容量(capacity)和大小(size)之间的区别,甚至有人认为它们表达的是一个意思.本节将对 vector 容量和大小各自的含义做一个详细的介绍. vect ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:表示信息变化的操作
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 首款中文渗透测试专用Linux系统—MagicBox
1. MagicBox的介绍 首款中文渗透测试专用Linux系统——MagicBox即将问世,中文名称:“魔方系统”,开发代号:Genesis.第一版本发布时间计划为2012年12月5日 这是 ...
- SAP BO WebI 如何连接webi server folder下面的EXCEL文件作为数据源
昨天做Webi Report,需要连接一个在Webi Server Folder下面的EXCEL文件作为数据源,然后再去生成相应的报表,找了半天才找到可以连接Webi Server Folder的EX ...
- java并发初探ThreadPoolExecutor拒绝策略
java并发初探ThreadPoolExecutor拒绝策略 ThreadPoolExecuter构造器 corePoolSize是核心线程池,就是常驻线程池数量: maximumPoolSize是最 ...
- 契约精神、尊重规则、SOP,对制造业来说是蜜糖还是毒药?
契约精神.尊重规则.执行SOP,这些词儿都天然带有光环,也有很多相关的好故事,全球范围内的企业家都对其推崇备至,摆出一副虔诚教徒的模样,事实上,缺乏契约精神.不遵守规则比之缺乏资本.丢掉订单更加不可接 ...