zoukankan      html  css  js  c++  java
  • BZOJ 2282 [Sdoi2011]消防

    题解:

    路径一定在直径上

    取出直径来

    在直径上枚举左右端点就可以了(A掉)

    但是可能会被卡

    所以枚举左端点,右端点单调,更新答案即可

    WOC ST表竟然打错了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int maxn=300009;
    
    int n,s;
    int ans=0x7fffffff;
    
    
    int cntedge=0;
    int head[maxn]={0};
    int to[maxn<<1]={0},nex[maxn<<1]={0},dist[maxn<<1]={0};
    void Addedge(int x,int y,int z){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	dist[cntedge]=z;
    	head[x]=cntedge;
    }
    
    int lu=0,ru=0;
    int father[maxn]={0};
    int d[maxn]={0};
    void Dfs(int now,int fa){
    	father[now]=fa;
    	for(int i=head[now];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		d[to[i]]=d[now]+dist[i];
    		Dfs(to[i],now);
    	}
    }
    
    int p[maxn],nn=0;
    int ond[maxn]={0};
    int h[maxn]={0};
    
    int GetMaxdep(int x,int fa){
    	int ret=0;
    	for(int i=head[x];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		if(ond[to[i]])continue;
    		ret=max(ret,dist[i]+GetMaxdep(to[i],x));
    	}
    	return ret;
    }
    
    int f[maxn][20];
    void STinit(int n){
    	for(int i=1;i<=n;++i)f[i][0]=h[i];
    	for(int j=1;j<=19;++j){
    		for(int i=1;i+(1<<j)-1<=n;++i){
    			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    		}
    	}
    }
    int Querymax(int l,int r){
    	int k=log2(r-l+1.5);
    	return max(f[l][k],f[r-(1<<k)+1][k]);
    }
    
    int main(){
    	scanf("%d%d",&n,&s);
    	for(int i=1;i<=n-1;++i){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		Addedge(x,y,z);
    		Addedge(y,x,z);
    	}
    	
    	d[1]=0;
    	Dfs(1,0);
    	lu=1;
    	for(int i=1;i<=n;++i){
    		if(d[i]>d[lu])lu=i;
    	}
    	
    	d[lu]=0;
    	Dfs(lu,0);
    	ru=1;
    	for(int i=1;i<=n;++i){
    		if(d[i]>d[ru])ru=i;
    	}
    	
    	int x=ru;
    	while(x){
    		p[++nn]=x;
    		ond[x]=1;
    		x=father[x];
    	}
    	
    	for(int i=1;i<=nn;++i){
    		int x=p[i];
    		h[i]=GetMaxdep(x,0);
    	}
    	
    //	for(int i=1;i<=nn;++i){
    //		for(int j=i;j<=nn;++j){
    //			if(d[p[i]]-d[p[j]]>s)continue;
    //			int tm=max(d[p[1]]-d[p[i]],d[p[j]]-d[p[nn]]);
    //			for(int k=i;k<=j;++k)tm=max(tm,h[k]);
    //			ans=min(ans,tm);
    //		}
    //	}
    	
    	STinit(nn);
    	int last=1;
    	for(int i=1;i<=nn;++i){
    		while(d[p[last]]-d[p[i]]>s)++last;
    		int tm=max(d[p[1]]-d[p[last]],d[p[i]]-d[p[nn]]);
    		tm=max(tm,Querymax(last,i));
    		ans=min(ans,tm);
    	}
    	
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    微信支付-我遇到的那些问题
    [工作笔记]JDK版本不同导致的SSL异常
    mysql与oracle在groupby语句上的细节差异
    微信js-sdk调用
    循序渐进看Java web日志跟踪(3)-Log4J的使用和配置
    循序渐进看Java web日志跟踪(2)-Java日志API认识
    循序渐进看Java web日志跟踪(1)-Tomcat 日志追踪与配置
    手机号码正则表达式(含虚拟运营商)
    网站URL重写(Java UrlRewrite 的使用)
    TCP/IP提供网络传输速率
  • 原文地址:https://www.cnblogs.com/zzyer/p/8504109.html
Copyright © 2011-2022 走看看