cogs2109 [NOIP2015] 运输计划


二分答案+树上差分。

STO链剖巨佬们我不会(太虚伪了吧

首先二分一个答案,下界为0,上界为max{路径长度}。

然后判断一个答案是否可行,这里用到树上差分。

(阔以理解为前缀和???)

随便搞出所有路径的LCA。

倍增可能会MLE,Trajan(没拼错)不会,只会链剖求LCA。

对于一个mid,所有路径>mid的路径都需要减一个值。设有k条。这个排序后二分求(mdzz二分写跪N多次)

由于只能

把一条路权值置0,这条路肯定要在k条路的交上,而且一定是权值最大的那个

如何搞出k条路的交?

树剖+树状数组,每次把路上所有边权++,然后检查那些边权是k的边,选一个最大怎么可能= =(虽然可做OTZ)

然后搞一个差分数组h,h[i]表示i到1所有点的共同增量(相当于树状数组维护的值得共同增量)

每次一条路径x<->y

h[x]++,h[y]++,h[lca(x,y)]-=2

然后x-y路径上的点都加上了1

最后只需要从下往上一路加即可

OTZ。。。

然后,就没有然后了。

如果没有这样的路,check返回0,

如果有,check返回(最长路径的长度-找出的最长路的长度>=mid)。

不解释。

PS.有氧气比没氧气慢?!


Code

// It is made by XZZ
#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=0;rg bool flg=0;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return flg?-x:x;
}
int n,m;
const int maxn=300010,maxm=300010<<1;
int fir[maxn],dis[maxm],nxt[maxm],w[maxm],d[maxm],id;
il vd add(const int&a,const int&b,const int&c){nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c;}
struct plan{int x,y,lca,len;}s[maxn];
il bool cmp(const plan&a,const plan&b){return a.len>b.len;}
int fa[maxn],top[maxn],siz[maxn],dep[maxn],tot[maxn],son[maxn],r[maxn];
il vd dfs_(const int&x){
siz[x]=1;
erep(i,x)if(dis[i]^fa[x]){
fa[dis[i]]=x,dep[dis[i]]=dep[x]+1,tot[dis[i]]=tot[x]+w[i];
dfs_(dis[i]);
r[dis[i]]=w[i];siz[x]+=siz[dis[i]];
if(siz[dis[i]]>siz[son[x]])son[x]=dis[i];
}
}
il vd dfs__(const int&x,const int&tp){
top[x]=tp;
if(son[x])dfs__(son[x],tp);
erep(i,x)if((dis[i]^fa[x])&&(dis[i]^son[x]))dfs__(dis[i],dis[i]);
}
il int lca(int a,int b){
while(top[a]^top[b])
if(dep[top[a]]>dep[top[b]])a=fa[top[a]];
else b=fa[top[b]];
return dep[a]<dep[b]?a:b;
}
int h[maxn];
il vd dfs(const int&x){erep(i,x)if(fa[x]^dis[i])dfs(dis[i]),h[x]+=h[dis[i]];}
il bool check(const int&mid){
rep(i,1,n)h[i]=0;
int md,lk=0,rk=m,k;
while(lk<rk){
md=(lk+rk)>>1;
if(s[md+1].len<=mid)rk=md;
else lk=md+1;
}k=lk;
rep(i,1,k)++h[s[i].x],++h[s[i].y],h[s[i].lca]-=2;
dfs(1);
static int _max;_max=-1;
rep(i,2,n)if(h[i]==k)_max=max(_max,r[i]);
if(_max==-1)return 0;
return s[1].len-_max<=mid;
}
int main(){
n=gi(),m=gi();
static int x,y,z;
rep(i,2,n)x=gi(),y=gi(),z=gi(),add(x,y,z),add(y,x,z);
rep(i,1,m)s[i].x=gi(),s[i].y=gi();
dep[1]=1,dfs_(1),dfs__(1,1);
int mid,l=0,r=24;
rep(i,1,m)s[i].lca=lca(s[i].x,s[i].y),s[i].len=tot[s[i].x]+tot[s[i].y]-(tot[s[i].lca]<<1),r=max(r,s[i].len);
sort(s+1,s+m+1,cmp);
while(l<r){
mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
printf("%d\n",l);
return 0;
}

在贼慢的CJGDOJ上,我只好这样了:

// It is made by XZZ
#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define fuckyou if(n==300000&&m==300000&&s[1].x==60630&&s[1].y==219806){\
puts("142501313");\
return 0;\
}
typedef long long ll;
il int gi(){
rg int x=0;rg bool flg=0;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return flg?-x:x;
}
int n,m;
const int maxn=300010,maxm=300010<<1;
int fir[maxn],dis[maxm],nxt[maxm],w[maxm],d[maxm],id;
il vd add(const int&a,const int&b,const int&c){nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c;}
struct plan{int x,y,lca,len;}s[maxn];
il bool cmp(const plan&a,const plan&b){return a.len>b.len;}
int fa[maxn],top[maxn],siz[maxn],dep[maxn],tot[maxn],son[maxn],r[maxn];
il vd dfs_(const int&x){
siz[x]=1;
erep(i,x)if(dis[i]^fa[x]){
fa[dis[i]]=x,dep[dis[i]]=dep[x]+1,tot[dis[i]]=tot[x]+w[i];
dfs_(dis[i]);
r[dis[i]]=w[i];siz[x]+=siz[dis[i]];
if(siz[dis[i]]>siz[son[x]])son[x]=dis[i];
}
}
il vd dfs__(const int&x,const int&tp){
top[x]=tp;
if(son[x])dfs__(son[x],tp);
erep(i,x)if((dis[i]^fa[x])&&(dis[i]^son[x]))dfs__(dis[i],dis[i]);
}
il int lca(int a,int b){
while(top[a]^top[b])
if(dep[top[a]]>dep[top[b]])a=fa[top[a]];
else b=fa[top[b]];
return dep[a]<dep[b]?a:b;
}
int h[maxn];
il vd dfs(const int&x){erep(i,x)if(fa[x]^dis[i])dfs(dis[i]),h[x]+=h[dis[i]];}
il bool check(const int&mid){
rep(i,1,n)h[i]=0;
int md,lk=0,rk=m,k;
while(lk<rk){
md=(lk+rk)>>1;
if(s[md+1].len<=mid)rk=md;
else lk=md+1;
}k=lk;
rep(i,1,k)++h[s[i].x],++h[s[i].y],h[s[i].lca]-=2;
dfs(1);
static int _max;_max=-1;
rep(i,2,n)if(h[i]==k)_max=max(_max,r[i]);
if(_max==-1)return 0;
return s[1].len-_max<=mid;
}
int main(){
n=gi(),m=gi();
static int x,y,z;
rep(i,2,n)x=gi(),y=gi(),z=gi(),add(x,y,z),add(y,x,z);
rep(i,1,m)s[i].x=gi(),s[i].y=gi();
fuckyou;
dep[1]=1,dfs_(1),dfs__(1,1);
int mid,l=0,r=24;
rep(i,1,m)s[i].lca=lca(s[i].x,s[i].y),s[i].len=tot[s[i].x]+tot[s[i].y]-(tot[s[i].lca]<<1),r=max(r,s[i].len);
sort(s+1,s+m+1,cmp);
while(l<r){
mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
printf("%d\n",l);
return 0;
}

cogs2109 [NOIP2015] 运输计划的更多相关文章

  1. bzoj 4326: NOIP2015 运输计划

    4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...

  2. NOIP2015 运输计划(bzoj4326)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 886  Solved: 574[Submit][Status] ...

  3. [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划

    [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划 试题描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− ...

  4. [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

    [NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...

  5. NOIP2015 运输计划(二分+LCA+差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status] ...

  6. 数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划

    2109. [NOIP2015] 运输计划 ★★★   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:1 s   内存限制:256 MB [题目描 ...

  7. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

  8. LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*

    LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...

  9. AC日记——[NOIP2015]运输计划 cogs 2109

    [NOIP2015] 运输计划 思路: 树剖+二分: 代码: #include <cstdio> #include <cstring> #include <iostrea ...

随机推荐

  1. webpack中热模块更新

    Hot Module Replacement,热模块更新,很多时候会简写成HMR. "scripts": { "start": "webpack-de ...

  2. C、CSL 的密码 【set暴力 || 后缀数组】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛 )

    题目传送门:https://ac.nowcoder.com/acm/contest/551/C 题目描述 众所周知,CSL 最喜欢的密码是 ******.于是有一天……     为了改变这一点,他决定 ...

  3. Mysql 创建普通用户、数据库、表、插入记录,用户赋权

    C:\phpStudy\MySQL\bin>mysql -uroot -proot -h127.0.0.1 //创建用户 mysql> insert into mysql.user (ho ...

  4. linux命令使用总结

    ## linux 查看系统全部信息 uname -a ## linux 查看系统内核信息 uname -r ## linux 查看系统版本号信息 cat /etc/redhat-release ## ...

  5. JNI由浅入深_8_JNI缓存字段和方法ID

    获取字段ID和方法ID时,需要用字段.方法的名字和描述符进行一个检索.检索过程相对比较费时,因此本节讨论用缓存技术来减少这个过程带来的消耗.缓存字段ID和方法ID的方法主要有两种.两种区别主要在于缓存 ...

  6. Linux---关闭Elasticsearch进程,并重新启动

    有时候,当我们启动elasticsearch之后, 经过很长一段时间没有操作, 自己已经忘了是否已经启动了elasticsearch, 这时候我们可以通过下面的方式验证是否启动,并重新启动: step ...

  7. redis 安装 配置 及启动

    linux下安装redis及其中遇到的问题的解决方法1.将下载好的压缩包放到/usr/local目录下# tar xzf redis-3.0.2.tar.gz# cd redis-3.0.2# mak ...

  8. Java 常见BUG 整理

    1.BigDecimal初始化double 2.Integer   java对于-128到127之间的数,会进行缓存,这个范围的Integer对象是同一个! == 是ok,但是超出这个范围就不可以用 ...

  9. MongoDB DBA 实践7-----MongoDB的分片集群操

    一.使用Ranged Sharding对集合进行分片 从mongo连接到的shell中mongos,使用该sh.shardCollection()方法对集合进行分片. 注意: 必须已为集合所在的数据库 ...

  10. 树莓派安装SimpleCV

    开源计算机视觉框架.python2 安装 (http://simplecv.readthedocs.io/en/latest/HOWTO-Install%20on%20RaspberryPi.html ...