[填坑][主線任務]歷年NOIP刷題計劃
阿新 • • 發佈:2017-11-06
今天 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刷題計劃