1999: [Noip2007]Core树网的核

来源:互联网 发布:武汉大学网络教学平台 编辑:程序博客网 时间:2024/05/24 04:57

参考了下面的博客。

http://blog.csdn.net/cyxhahaha/article/details/47345999

对于所选路径上的任一点x,记Max[x]为从x出发,不经过直径上其他点到达的最远点的距离,对于一条以y,z为端点的路径(dep[y]<=dep[z]),可计算出此时的偏心距=max(max(dep[y],d-dep[y]),max(Max[x]))对每次计算出的偏心距取min就没了。这个要用单调队列维护,使得元素的Max递减。原因如下:

同时要用s来限制队首的位置。这样可以把max(Max[x])变成Max[队首]。

做完了。

然而我并没有A掉。明明codevs和洛谷都过了,却没在BZOJ上A掉。我也不知道为什么。

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cstdlib>using namespace std;#define rep(i,j,k) for(i=j;i<=k;++i)#define per(i,j,k) for(i=j;i>=k;--i)#define ll long long#define db double#define mkp(x,y) make_pair(x,y)#define pii pair<int,int>#define X first#define Y secondconst int N=500005;int n,s,ans;int he[N],ne[N<<1],to[N<<1],W[N<<1],tot;int dep[N],pre[N],rt,md,D,Max[N];int tmp[N],ln,q[N],Ft,Rr;void add(int x,int y,int z){    W[++tot]=z;to[tot]=y;ne[tot]=he[x];he[x]=tot;}void DFS1(int x,int e){    int y,i;    for(i=he[x];i;i=ne[i])if(i!=e){        dep[y=to[i]]=dep[x]+W[i];DFS1(y,i^1);    }}void DFS2(int x,int e){    int y,i;    for(i=he[x];i;i=ne[i])if(i!=e){        dep[y=to[i]]=dep[x]+W[i];pre[y]=x;DFS2(y,i^1);    }}int DFS3(int x,int e){    int y,i,rtn=0;    for(i=he[x];i;i=ne[i])if(i!=e){        rtn=max(rtn,W[i]+DFS3(to[i],i^1));    }    return rtn;}int main(){    int i,j,x,y,z;    scanf("%d%d",&n,&s);tot=1;    rep(i,2,n){        scanf("%d%d%d",&x,&y,&z);        add(x,y,z),add(y,x,z);    }    DFS1(rt=1,0);    rep(i,2,n)if(dep[rt]<dep[i])rt=i;    memset(dep,0,sizeof dep);    DFS2(rt,0);D=dep[md=1];    rep(i,2,n)if(D<dep[i])D=dep[md=i];    for(tmp[ln=1]=x=md;x!=rt;x=y){        z=pre[tmp[++ln]=y=pre[x]];        for(i=he[y];i;i=ne[i])if(to[i]!=z&&to[i]!=x)            Max[y]=max(Max[y],W[i]+DFS3(to[i],i^1));    }    ans=250000001;Rr=1;j=1;    rep(i,1,n){        while(j<=ln&&(Ft==Rr||dep[tmp[i]]-dep[tmp[j]]<=s)){            while(Ft<Rr&&Max[q[Rr-1]]<=Max[tmp[j]])Rr--;q[Rr++]=tmp[j++];            ans=min(ans,max(Max[tmp[i]],max(dep[q[Rr-1]],D-dep[tmp[i]])));        }        if(q[Ft]==tmp[i])++Ft;    }    printf("%d\n",ans);    return 0;}

原创粉丝点击