[BZOJ2282] [Sdoi2011]消防

Posted Nawox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ2282] [Sdoi2011]消防相关的知识,希望对你有一定的参考价值。

 

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 # define maxn 300010
  8 using namespace std;
  9 void ot(){cout<<"****"<<endl;}
 10 int n;
 11 int m;
 12 struct node{
 13     int u,v,w,nxt;
 14 }g[2*maxn];
 15 int adj[maxn],e;
 16 void add(int u,int v,int w){
 17     g[e]=(node){u,v,w,adj[u]};
 18     adj[u]=e++;
 19 }
 20 int pre[maxn],dis[maxn];
 21 bool vis[maxn],pd[maxn];
 22 int q[maxn],head,tail;
 23 int st,ed,mx_dis,mn_dis;
 24 int lin[maxn],top;
 25 void beg(){
 26     head=tail=1;
 27     q[tail++]=1; vis[1]=1;
 28     int mx=0;
 29     while(head<tail){
 30         int k=q[head++];
 31         for(int i=adj[k];i!=-1;i=g[i].nxt){
 32             int v=g[i].v; if(vis[v]) continue;
 33             dis[v]=dis[k]+g[i].w; vis[v]=1;
 34             if(dis[v]>mx) mx=dis[v],st=v;
 35             q[tail++]=v;
 36         }
 37     }
 38     memset(vis,0,sizeof(vis));
 39     memset(dis,0,sizeof(dis));
 40     head=tail=1; mx=0;
 41     q[tail++]=st; vis[st]=1;
 42     while(head<tail){
 43         int k=q[head++];
 44         for(int i=adj[k];i!=-1;i=g[i].nxt){
 45  
 46             int v=g[i].v; if(vis[v]) continue;
 47             dis[v]=dis[k]+g[i].w; vis[v]=1;
 48             pre[v]=k;
 49             if(dis[v]>mx) mx=dis[v],ed=v; 
 50             q[tail++]=v;
 51         }
 52     }
 53     mx_dis=mx;
 54     int x=ed;
 55     while(x){
 56         pd[x]=1; lin[++top]=dis[x];
 57         x=pre[x];
 58     }
 59     memset(vis,0,sizeof(vis));
 60     memset(dis,0,sizeof(dis));
 61     head=tail=1; mx=0;
 62     q[tail++]=ed; vis[ed]=1;
 63     while(head<tail){
 64         int k=q[head++];
 65         for(int i=adj[k];i!=-1;i=g[i].nxt){
 66             int v=g[i].v; if(vis[v]) continue;
 67             vis[v]=1;
 68             if(pd[v]) dis[v]=dis[k];
 69             else dis[v]=dis[k]+g[i].w;
 70             mx=max(mx,dis[v]);
 71             q[tail++]=v;
 72         }
 73     }
 74     mn_dis=mx;
 75 }
 76 bool check(int x){
 77     int l=1,r=top;
 78     while(lin[1]-lin[l+1]<=x && l<=top) l++;
 79     while(lin[r-1]-lin[top]<=x && r>=1) r--;
 80     // cout<<"lr== "<<l<<"  "<<r<<endl;
 81     // cout<<lin[l]<<"  * "<<lin[r]<<endl;
 82     return lin[l]-lin[r]<=m?1:0;
 83 }
 84 int main(){
 85     // freopen("a.in","r",stdin);
 86     scanf("%d%d",&n,&m);
 87     int x,y,z;
 88     memset(adj,-1,sizeof(adj));
 89     for(int i=1;i<n;i++){
 90         scanf("%d%d%d",&x,&y,&z);
 91         add(x,y,z); add(y,x,z);
 92     }
 93     beg();
 94     int l=mn_dis,r=mx_dis,mid,ans;
 95     // for(int i=1;i<=n;i++) cout<<pd[i]<<" "; cout<<endl;
 96     // cout<<"top= "<<top<<endl;
 97     // for(int i=1;i<=top;i++) cout<<lin[i]<<" "; cout<<endl;
 98     // cout<<check(5)<<endl; exit(0);
 99     while(l<=r){
100         mid=(l+r)>>1;
101         if(check(mid)) ans=mid,r=mid-1;
102         else l=mid+1;
103     }
104     cout<<ans<<endl;
105 }

 

以上是关于[BZOJ2282] [Sdoi2011]消防的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2282[Sdoi2011]消防 树形DP+双指针法+单调队列

BZOJ 2282 [Sdoi2011]消防

bzoj2282 [SDOI2011]消防

消防(bzoj 2282)

[SDOI2011]消防

[Sdoi2011]消防