【BZOJ1999】【NOIP2007】树网的核 单调队列优化DP
来源:互联网 发布:js监听扫描枪 编辑:程序博客网 时间:2024/05/20 20:03
题目描述
题目很长,大家自己去看吧。
bzoj
vijos
原题
加强版
题解
这种东西当然要猜结论的啦,否则会比较麻烦。
结论1:如果有很多条直径,那么不管核在哪条直径上,最小偏心距都相同。
结论2 :任意一条路径的偏心距不会小于核的最小偏心距。
这两个结论的证明方法类似。都是考虑两条路径的公共部分和非公共部分。如果最远的点到路径上的最近的点都在公共部分上,则偏心距相同。任意两条直径的非公共部分长度相同,最远的点到直径上的最近的点的距离显然大于最远的点到其他路径上的最近的点的距离(否则这条直径就不是直径了)。
结论1告诉我们可以只考虑一条路径,结论2告诉我们可以考虑所有
对于
算最短路用floyd
时间复杂度:
对于
时间复杂度:
代码
//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;}
阅读全文
0 0
- 【BZOJ1999】【NOIP2007】树网的核 单调队列优化DP
- BZOJ1999 && noip2007树网的核
- 1999: [Noip2007]Core树网的核 树形dp 单调队列
- 【BZOJ1999】树网的核,求树的直径+单调队列乱搞
- BZOJ1999(Noip2007)[Core树网的核]--最长链+DFS大法
- bzoj1990 NOIP2007 树网的核 树的直径&单调队列维护最小值
- 单调队列优化的DP
- 单调队列 和单调队列优化的dp
- 单调队列优化DP
- 单调队列优化DP
- dp单调队列优化
- 单调队列--优化dp
- 单调队列优化dp
- 单调队列优化DP
- 单调队列优化DP
- 单调队列优化dp
- 单调队列+斜率优化的DP
- 【专辑】单调队列+斜率优化的DP
- 2017.11.10心得
- 共享池抖动分析脚本
- Linux 文件查看与排序
- 解决windows系统bootmgr is missing
- 运维之mysql篇------2. MySQL 索引类型 、 MySQL 存储引擎
- 【BZOJ1999】【NOIP2007】树网的核 单调队列优化DP
- php 使用mysql数据库增删改查
- 关于安卓开发之支付功能
- node文件上传
- ONVIF 开发过程总结(C++) (一)
- android 深入了解layout_weight属性
- 学生成绩(类的应用)
- PYG电商项目开发 -- day01 电商介绍及工程搭建
- 编程的智慧