【BZOJ1999】【NOIP2007】树网的核 单调队列优化DP
题目描述
题目很长,大家自己去看吧。
原题\(n\leq 300\)
加强版\(n\leq 500000\)
题解
这种东西当然要猜结论的啦,否则会比较麻烦。
结论1:如果有很多条直径,那么不管核在哪条直径上,最小偏心距都相同。
结论2 :任意一条路径的偏心距不会小于核的最小偏心距。
这两个结论的证明方法类似。都是考虑两条路径的公共部分和非公共部分。如果最远的点到路径上的最近的点都在公共部分上,则偏心距相同。任意两条直径的非公共部分长度相同,最远的点到直径上的最近的点的距离显然大于最远的点到其他路径上的最近的点的距离(否则这条直径就不是直径了)。
结论1告诉我们可以只考虑一条路径,结论2告诉我们可以考虑所有\(O(n^2)\)条路径而不用管这条路径是否在直径上。
对于\(n\leq 300\),直接暴力枚举路径的两个端点,枚举任意一个点,算出所有其他点到这条路径的距离,就是(这个点到一个端点的距离\(+\)这个点到另一个端点的距离\(-\)这条路径的长度)\(\div 2\),算出最大值然后更新答案。
算最短路用floyd
时间复杂度:\(O(n^3)\)
对于\(n\leq 500000\),找出其中一条直径,把这条直径拿出来,算出每个点往右距离不超过\(s\)的点是哪个,算出每个点忽略直径上左边所有点/右边所有点/左边+右边所有点的最远距离。这三部分的最大值就是一条路径的答案。然后从右往左计算答案,用单调队列维护答案:如果新加入队列的偏心距比队尾的偏心距大,可以把队尾删掉。算出所有路径的答案然后取\(\min\)就可以了。
时间复杂度:\(O(n)\)
代码
//O(n^3)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
int f[310][310];
int main()
{
int n,s;
scanf("%d%d",&n,&s);
memset(f,0x3f,sizeof f);
int i,x,y,z;
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
f[x][y]=f[y][x]=z;
}
for(i=1;i<=n;i++)
f[i][i]=0;
int j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
if(i!=k)
for(j=1;j<=n;j++)
if(j!=i&&j!=k)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
int ans=0x7fffffff;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(f[i][j]<=s)
{
int now=0;
for(k=1;k<=n;k++)
now=max(now,(f[k][i]+f[k][j]-f[i][j])/2);
ans=min(ans,now);
}
printf("%d\n",ans);
return 0;
}
//O(n)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
#include<queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
struct graph
{
int v[1000010];
int w[1000010];
int t[1000010];
int h[500010];
int n;
graph()
{
memset(h,0,sizeof h);
n=0;
}
void add(int x,int y,int z)
{
n++;
v[n]=y;
w[n]=z;
t[n]=h[x];
h[x]=n;
}
};
graph g;
int from[500010];
int b[500010];
queue<int> q;
int d[500010];
int w[500010];
void bfs(int x)
{
memset(d,-1,sizeof d);
d[x]=0;
q.push(x);
int i;
from[x]=0;
w[x]=0;
while(!q.empty())
{
x=q.front();
q.pop();
for(i=g.h[x];i;i=g.t[i])
if(d[g.v[i]]==-1)
{
d[g.v[i]]=d[x]+g.w[i];
w[g.v[i]]=g.w[i];
from[g.v[i]]=x;
q.push(g.v[i]);
}
}
}
void dfs(int x,int fa,int dep,int &s)
{
s=max(s,dep);
int i;
for(i=g.h[x];i;i=g.t[i])
if(!b[g.v[i]]&&g.v[i]!=fa)
dfs(g.v[i],x,dep+g.w[i],s);
}
int a[500010];
int c[500010];
int f[500010];
int fl[500010];
int fr[500010];
pii q2[500010];
int head,tail;
void add(int x)
{
while(tail>=head&&q2[tail].second<=f[x])
tail--;
q2[++tail]=pii(x,f[x]);
}
void del(int x)
{
if(q2[head].first==x)
head++;
}
int main()
{
freopen("bzoj1999.in","r",stdin);
freopen("bzoj1999.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
int i,x,y,z;
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
g.add(x,y,z);
g.add(y,x,z);
}
bfs(1);
x=1;
for(i=1;i<=n;i++)
if(d[i]>d[x])
x=i;
bfs(x);
for(i=1;i<=n;i++)
if(d[i]>d[x])
x=i;
int t=0;
do
{
a[++t]=x;
c[t]=w[x];
x=from[x];
}
while(x);
for(i=1;i<=t;i++)
b[a[i]]=1;
int j;
for(i=1;i<=t;i++)
for(j=g.h[a[i]];j;j=g.t[j])
if(!b[g.v[j]])
dfs(g.v[j],0,g.w[j],f[i]);
for(i=1;i<=t;i++)
fl[i]=max(f[i],fl[i-1]+c[i-1]);
for(i=t;i>=1;i--)
fr[i]=max(f[i],fr[i+1]+c[i]);
for(i=1;i<=t;i++)
c[i]+=c[i-1];
head=1;
tail=0;
j=1;
int ans=0x7fffffff;
for(i=1;i<=t;i++)
{
add(i);
while(c[i-1]-c[j-1]>m)
{
del(j);
j++;
}
ans=min(ans,max(max(fl[j],fr[i]),q2[head].second));
}
printf("%d\n",ans);
return 0;
}
【BZOJ1999】【NOIP2007】树网的核 单调队列优化DP的更多相关文章
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- bzoj1855: [Scoi2010]股票交易--单调队列优化DP
单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...
- hdu3401:单调队列优化dp
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
- Parade(单调队列优化dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
- BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...
- 【单调队列优化dp】 分组
[单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- 单调队列以及单调队列优化DP
单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
随机推荐
- SQL SERVER中的两种常见死锁及解决思路
在sql server中,死锁都与一种锁有关,那就是排它锁(x锁).由于在同一时间对同一个数据库资源只能有一个数据库进程可以拥有排它锁.因此,一旦多个进程都需要获取某个或者同一个数据库资源的排它访问权 ...
- Python-认识正则表达式-53
# 计算器# re模块# 正则表达式 —— 字符串匹配的# 学习正则表达式# 学习使用re模块来操作正则表达式 #判断手机号是否符合要求 while True: phone_number = inpu ...
- shell脚本--编写CGI代码(shell结合html)以及环境变量
实现shell和html标签混合的方式编写代码: 推荐 初始CGI ,看完大概之后,大概对cgi有个大体的印象.下面是编写混合代码的示例: #!/bin/bash #index.cgi echo & ...
- 爬虫——scrapy框架
Scrapy是一个异步处理框架,是纯Python实现的爬虫框架,其架构清晰,模块之间的耦合程度低,可拓展性强,可以灵活完成各种需求.我们只需要定制几个模块就可以轻松实现一个爬虫. 1.架构 Scra ...
- TortoiseGit push免输密码
(ฅ>ω<*ฅ) 噫又好了~ TortoiseGit push免输密码的方法 – 晨旭的博客~https://www.chenxublog.com/2016/03/04/tortoiseg ...
- .Net MVC4 log4net的配置
一.首先在使用log4net记录日志的时候,我们要引用log4net.dll文件 二.在web.config中添加一下配置代码 <configSections> <!-- For m ...
- Codeforces 1154C Gourmet Cat
题目链接:http://codeforces.com/problemset/problem/1154/C 题目大意: 主人有一只猫.周一&周四&周日:吃鱼周二&周六:吃兔子周三 ...
- JS--innerHTML属性
innerHTML属性,不是DOM的组成部分(常用) 获取标签里的文本内容,var span=document.getElementById("span").innerHTML; ...
- Intel HD Graphics 620 (华硕FL5900U) Windows7下安装显卡驱动
我们的牙膏大厂Intel,不但会挤牙膏,现在连驱动也不给你用了.KabyLake也就是第七代酷睿处理器,集成了Intel HD Graphics 620核显,核显(显卡)驱动程序只支持到Win10这一 ...
- Spring Boot 构建电商基础秒杀项目 (六) 用户登陆
SpringBoot构建电商基础秒杀项目 学习笔记 userDOMapper.xml 添加 <select id="selectByTelphone" resultMap=& ...