标签:pos head www. inline false stream void noip std
今天又是喜闻乐见的非考试日,那么今天做点什么呢==
前些日子的主线任务陆陆续续(接近)完成了,好多蒙蔽的没学好的算法都算是入门补坑了
我听学长说,做题的顺序是:NOIP真题->NOIP模拟题->专项练习->杂题
啊哈!最重要的真题我还没做几道呢...于是这两天填填这个坑吧

NOIP2016最难的题没有之一QAQ,原来做过一直没过,今天重新听讲解,总算打了出来
压轴题防AK,最后一个点及其凶残,并没有过去,跑了1.7s,无奈只能打表QAQ
其实打的是正解:LCA+二分答案+树上查分,可能是人傻自带超大常数T-T
95分代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);++i)
#define N 301000
inline int read(){
int sum(0);char ch=getchar();
while(ch<‘0‘||ch>‘9‘) ch=getchar();
while(ch>=‘0‘&&ch<=‘9‘){
sum=sum*10+ch-‘0‘;
ch=getchar();
}
return sum;
}
int n,m;
struct haha{
int next,to,w;
}edge[N*2];
int head[N],cnt=1;
void add(int u,int v,int w){
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int dis[N],dis2[N],fa[N],dep[N],wei[N];
void dfs(int x){
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to,w=edge[i].w;
if(to!=fa[x]){
fa[to]=x;
dep[to]=dep[x]+1;
dis2[to]=dis2[x]+w;
wei[to]=w;
dfs(to);
}
}
}
int p[N][20];
void init(){
for(int j=0;(1<<j)<=n;j++) pos(i,1,n) p[i][j]=-1;
pos(i,1,n) p[i][0]=fa[i];
for(int j=1;(1<<j)<=n;j++){
pos(i,1,n) if(p[i][j-1]!=-1) p[i][j]=p[p[i][j-1]][j-1];
}
}
int lca(int a,int b){
if(dep[a]<dep[b]) swap(a,b);
int i;for(i=0;(1<<i)<=dep[a];i++);i--;
for(int j=i;j>=0;j--) if(dep[a]-(1<<j)>=dep[b]) a=p[a][j];
if(a==b) return a;
for(int j=i;j>=0;j--) if(p[a][j]!=-1&&p[a][j]!=p[b][j]){
a=p[a][j];b=p[b][j];
}
return fa[a];
}
int cuns[N],cunt[N];
int l,r,size[N],lc[N];
void dfs2(int x){
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to!=fa[x]){
dfs2(to);
size[x]+=size[to];
}
}
}
bool check(int num){
int temp(0),jishu(0);
pos(i,1,n) size[i]=0;
pos(i,1,m){
if(dis[i]>num){
++jishu;
if(dis[i]-num>temp) temp=dis[i]-num;
++size[cuns[i]];++size[cunt[i]];size[lc[i]]-=2;
}
}
dfs2(1);
pos(i,2,n){
if(size[i]==jishu&&wei[i]>=temp) return true;
}
return false;
}
int main(){
n=read();m=read();
pos(i,1,n-1){
int x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z);
}
dfs(1);
init();
pos(i,1,m){
cuns[i]=read(),cunt[i]=read();
lc[i]=lca(cuns[i],cunt[i]);
dis[i]=dis2[cuns[i]]+dis2[cunt[i]]-2*dis2[lc[i]];
if(dis[i]>r) r=dis[i];
}
while(l+1<r){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid;
}
cout<<r<<endl;
return 0;
}
标签:pos head www. inline false stream void noip std
原文地址:http://www.cnblogs.com/Hallmeow/p/7792634.html