2282: [Sdoi2011]消防 树的直径+二分答案
来源:互联网 发布:dns设置软件 编辑:程序博客网 时间:2024/06/10 03:53
显然这条路径在树的直径上,随便YY一下就知道了这个。
开始写的DFS据说会爆栈= =于是改成了BFS。
然后我们求出直径,就可以二分答案,双指针向里缩,最后看两个指针之间距离是否合法。
#include<iostream>#include<cstdio>#include<cstring>#define N 300005using namespace std;int n,s,cnt,top,S,T;int dis[N],q[N],stack[N],head[N],from[N];bool mark[N];int next[N<<1],list[N<<1],key[N<<1];inline int read(){ int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f;}inline void insert(int x,int y,int z){ next[++cnt]=head[x]; head[x]=cnt; list[cnt]=y; key[cnt]=z;}inline void bfs(int st){ memset(dis,-1,sizeof(dis)); int t=0,w=1; q[1]=st; dis[st]=0; while (t<w) { int x=q[++t]; for (int i=head[x];i;i=next[i]) if (dis[list[i]]==-1) { from[list[i]]=x; dis[list[i]]=dis[x]+key[i]; q[++w]=list[i]; } }}inline void find_path(){ int x=T; stack[++top]=dis[x]; mark[x]=1; while (x!=S) stack[++top]=dis[from[x]],x=from[x],mark[x]=1;}inline void calc_dis(int st){ memset(dis,-1,sizeof(dis)); int t=0,w=1; q[1]=st; dis[st]=0; while (t<w) { int x=q[++t]; for (int i=head[x];i;i=next[i]) if (dis[list[i]]==-1) { if (mark[list[i]]) dis[list[i]]=dis[x]; else dis[list[i]]=dis[x]+key[i]; q[++w]=list[i]; } }}inline bool judge(int mid){ int l=1,r=top; while (stack[1]-stack[l+1]<=mid&&l<=top) l++; while (stack[r-1]<=mid&&r) r--; return stack[l]-stack[r]<=s;}int main(){ n=read(); s=read(); for (int i=1;i<n;i++) { int u=read(),v=read(),w=read(); insert(u,v,w); insert(v,u,w); } bfs(1); for (int i=1;i<=n;i++) if (dis[i]>dis[S]) S=i; bfs(S); for (int i=1;i<=n;i++) if (dis[i]>dis[T]) T=i; int l=0,r=dis[T]; find_path(); calc_dis(S); for (int i=1;i<=n;i++) l=max(l,dis[i]); while (l<=r) { int mid=l+r>>1; if (judge(mid)) r=mid-1; else l=mid+1; } cout << l << endl; return 0;}
0 0
- 2282: [Sdoi2011]消防 树的直径+二分答案
- 二分+树的直径 [Sdoi2011]消防
- bzoj 2282: [Sdoi2011]消防(树的直径+二分)
- Bzoj 2282: [Sdoi2011]消防(二分答案)
- [BZOJ]2282: [Sdoi2011]消防 树的直径+单调队列
- NKOJ 2650 (SDOI 2011) 消防(树的直径+DP+单调队列/二分答案)
- 【BZOJ2282】【Sdoi2011】消防 树的直径+双指针+单调队列 有一系列乱七八糟的证明
- 2282: [Sdoi2011]消防
- BZOJ 2282: [Sdoi2011]消防
- bzoj 2282: [Sdoi2011]消防
- bzoj 2282: [Sdoi2011]消防
- [BZOJ2282][Sdoi2011]消防(二分+贪心)
- [bzoj2282][Sdoi2011]消防(树上乱搞+二分)
- BZOJ 1999 [Noip2007]树网的核(2282 [Sdoi2011]消防)
- 避难向导 树的直径 树上倍增 二分答案
- [SDOI2011]消防
- nkoj 1313(noip2007)树网的核 与 nkoj 2650(SDOI2011)消防
- ZOJ 3684 Destroy 树的直径+二分
- 在一个Servlet中处理多个请求方法
- 2015年 年度总结
- JavaScript高级程序设计第三版笔记(基础部分)
- 七田式英语学习法的 7 条原则
- 复数的物理意义
- 2282: [Sdoi2011]消防 树的直径+二分答案
- shell 10进制转16进制输出
- 2016小感悟(一)
- 重点:用户画像
- I/O多路转接之select、poll、epoll
- Codeforces Round #342 (Div. 2) 625C K-special Tables(脑洞)
- poj 3624 Charm Bracelet
- 【C语言】C语言数据类型
- web CSS3伪类选择器 :nth-child()