首页 > 代码库 > AC日记——[NOIP2015]运输计划 cogs 2109
AC日记——[NOIP2015]运输计划 cogs 2109
[NOIP2015] 运输计划
思路:
树剖+二分;
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define maxn 300005#define INF 0x7fffffffint n,deep[maxn],dis[maxn],dis_[maxn],f[maxn],top[maxn];int head[maxn],E[maxn<<1],V[maxn<<1],W[maxn<<1],cnt,m;int path1[maxn],path2[maxn],ti[maxn],lar[maxn],size[maxn];int lca[maxn],lit_r,set[maxn];inline void in(int &now){ char Cget=getchar();now=0; while(Cget>‘9‘||Cget<‘0‘) Cget=getchar(); while(Cget>=‘0‘&&Cget<=‘9‘) { now=now*10+Cget-‘0‘; Cget=getchar(); }}void dfs1(int now,int fa){ deep[now]=deep[fa]+1,f[now]=fa,size[now]=1; for(int i=head[now];i;i=E[i]) { if(V[i]==fa) continue; dis[V[i]]=W[i]+dis[now],dfs1(V[i],now),size[now]+=size[V[i]]; if(size[lar[now]]<size[V[i]]) lar[now]=V[i]; }}void dfs2(int now,int chain){ top[now]=chain,dis_[now]=dis[now]-dis[f[now]]; if(lar[now]) dfs2(lar[now],chain);else return; for(int i=head[now];i;i=E[i]) { if(V[i]==f[now]||V[i]==lar[now]) continue; dfs2(V[i],V[i]); }}void tree_lca(int op){ int x=path1[op],y=path2[op],&ci=ti[op]; ci=dis[x]+dis[y]; for(;top[x]!=top[y];) { if(deep[top[x]]<deep[top[y]]) swap(x,y); x=f[top[x]]; } if(deep[x]>deep[y]) swap(x,y); lca[op]=x,lit_r=max(ci,lit_r); ci-=dis[lca[op]]*2;}void dfs3(int now){ for(int i=head[now];i;i=E[i]) { if(V[i]==f[now]) continue; dfs3(V[i]),dis[now]+=dis[V[i]]; } if(dis[now]==lit_r) set[++cnt]=now;}bool check(int x){ int num=0,pos=0; memset(dis,0,4*n+4); for(int i=1;i<=m;i++) { if(ti[i]>x) { num++;if(ti[i]>ti[pos]) pos=i; dis[path1[i]]++,dis[path2[i]]++,dis[lca[i]]-=2; } } if(!num) return true; cnt=0,lit_r=num,dfs3(1);pos=ti[pos]; for(int i=1;i<=cnt;i++) if(pos-dis_[set[i]]<=x) return true; return false;}int main(){ in(n),in(m);int u,v,w; for(int i=1;i<n;i++) { in(u),in(v),in(w); E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt; E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt; } cnt=0,dfs1(1,0),dfs2(1,1); for(int i=1;i<=m;i++) in(path1[i]),in(path2[i]),tree_lca(i); int l=0,r=lit_r,ans=INF;lit_r=0; while(l<=r) { int mid=l+r>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); return 0;}
AC日记——[NOIP2015]运输计划 cogs 2109
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。