1. 程式人生 > >[填坑][主線任務]歷年NOIP刷題計劃

[填坑][主線任務]歷年NOIP刷題計劃

今天 getc htm 過去 講解 練習 二分 1.7 一個

今天又是喜聞樂見的非考試日,那麽今天做點什麽呢==

前些日子的主線任務陸陸續續(接近)完成了,好多蒙蔽的沒學好的算法都算是入門補坑了

我聽學長說,做題的順序是:NOIP真題->NOIP模擬題->專項練習->雜題

啊哈!最重要的真題我還沒做幾道呢...於是這兩天填填這個坑吧

技術分享

[NOIP2016 Day1 T2]天天愛跑步

NOIP2016最難的題沒有之一QAQ,原來做過一直沒過,今天重新聽講解,總算打了出來

[NOIP2015 Day2 T3]運輸計劃

壓軸題防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;
} 

  

[填坑][主線任務]歷年NOIP刷題計劃