zoukankan      html  css  js  c++  java
  • ●BZOJ 2500 幸福的道路

    题链:

    http://www.lydsy.com/JudgeOnline/problem.php?id=2500

    题解:

    DFS,单调队列


    首先有一个结论,距离树上某一个点最远的点一定是树的直径的一个端点。


    然后就3个DFS求出直接并得到D[i]数组表示i点到最远的点的距离。


    然后就用两个单调队列分别维护一个单减的最大值和一个单增的最小值,

    以便求出以i位置结尾的最长合法区间。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXN 1000500
    #define rint register int
    using namespace std;
    struct Edge{
    	int to[MAXN*2],val[MAXN*2],nxt[MAXN*2],head[MAXN],ent;
    	Edge(){ent=2;}
    	void Adde(int &u,int &v,int &w){
    		to[ent]=v; val[ent]=w; nxt[ent]=head[u]; head[u]=ent++;
    		to[ent]=u; val[ent]=w; nxt[ent]=head[v]; head[v]=ent++;
    	}
    }E;
    int D[MAXN];
    int N,M,d1,d2,val;
    char gc(){
    	//return getchar();
    	static char s[300005];
    	static int bit=300000,p=0,len=0;
    	if(p>=len) len=fread(s,1,bit,stdin),s[len]=EOF,p=0;
    	return s[p++];
    }
    void read(int &x){
    	static int sn; static char ch;
    	x=0; sn=1; ch=gc();
    	while(ch<'0'||'9'<ch){if(ch=='-')sn=-1;ch=gc();}
    	while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=gc();}
    	x=x*sn;
    }
    void cmax(int &a,int b){
    	if(a<b) a=b;
    }
    void dfs(int u,int fa,int len,int &d){
    	if(len>=val) d=u,val=len;
    	cmax(D[u],len);
    	for(int i=E.head[u];i;i=E.nxt[i]){
    		if(E.to[i]==fa) continue;
    		dfs(E.to[i],u,len+E.val[i],d);
    	}
    }
    int solve(){
    	static int qmx[MAXN],qmn[MAXN],lmx=1,rmx=0,lmn=1,rmn=0,ANS=0,p=1;
    	for(int i=1;i<=N;i++){
    		while(lmx<=rmx&&D[qmx[rmx]]<=D[i]) rmx--;
    		while(lmn<=rmn&&D[qmn[rmn]]>=D[i]) rmn--;
    		qmx[++rmx]=i; qmn[++rmn]=i;
    		while(D[qmx[lmx]]-D[qmn[lmn]]>M){
    			if(qmx[lmx]<qmn[lmn]) p=qmx[lmx]+1,lmx++;
    			else p=qmn[lmn]+1,lmn++;
    		}
    		cmax(ANS,i-p+1);
    	}
    	return ANS;
    }
    int main(){
    	read(N); read(M); 
    	for(rint i=2,f,d;i<=N;i++)
    		read(f),read(d),E.Adde(f,i,d);
    	val=0; dfs(1,0,0,d1);
    	val=0; dfs(d1,0,0,d2);
    	val=0; dfs(d2,0,0,d1);
    	printf("%d",solve());
    	return 0;
    }
    

      

  • 相关阅读:
    手写vector
    Linux文件寻址算法:逻辑地址到物理地址的转换
    东北大学操作系统实验:进程同步和通信(生产者消费者问题模拟)
    操作系统页面置换算法之FIFO,LRU
    火车进站
    进程状态转换及其PCB的变化
    iOS ViewController里代码结构的规定
    mac下搭建https服务器
    openssl生成证书
    mac下 apacha tomcat相关操作
  • 原文地址:https://www.cnblogs.com/zj75211/p/8168860.html
Copyright © 2011-2022 走看看