• BZOJ3784: 树上的路径


    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3784

    题解:终于了结了好久以来的一个大坑。。。

            原来想的是怎么能点分治并且用堆的写法?今天发现真的可以这样做!!!

            我们在点分的时候直接把每个状态保存下来(时间允许,所以空间一定允许)。然后对每个区间保存一个区间[l,r]表示他可以从与[l,r]的节点构成一条完整的路径。

            这样在堆里把每个元素x放入,存为一个四元组(l,r,x,y)表示是x可以与[l,r]的节点构成路径,这其中最长的是y。然后每次取出最大之后就可以放入(l,y-1,x,max(l,y-1))和(y+1,r,x,max(y+1,r))

            最大值用st表预处理一下即可。真是Orz黄学长!!!

    代码:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<iostream>
      7 #include<vector>
      8 #include<map>
      9 #include<set>
     10 #include<queue>
     11 #include<string>
     12 #define inf 1000000000
     13 #define maxn 50000+5
     14 #define maxm 1000000+5
     15 #define eps 1e-10
     16 #define ll long long
     17 #define ull unsigned long long
     18 #define pa pair<int,int>
     19 #define for0(i,n) for(int i=0;i<=(n);i++)
     20 #define for1(i,n) for(int i=1;i<=(n);i++)
     21 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     22 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     23 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
     24 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
     25 #define mod 1000000007
     26 #define lch k<<1,l,mid
     27 #define rch k<<1|1,mid+1,r
     28 #define sqr(x) (x)*(x)
     29 using namespace std;
     30 inline int read()
     31 {
     32     int x=0,f=1;char ch=getchar();
     33     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     34     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     35     return x*f;
     36 }
     37 int n,m,l,r,sum,tot,rt,s[maxn],ss[maxn],head[maxn];
     38 bool del[maxn];
     39 int f[maxm][2],g[maxm],mx[maxm][21];
     40 struct edge{int go,next,w;}e[2*maxn];
     41 struct rec
     42 {
     43     int l,r,x,y;
     44 };
     45 bool operator <(rec a,rec b){return g[a.x]+g[a.y]<g[b.x]+g[b.y];}
     46 priority_queue<rec>q;
     47 inline void add(int x,int y,int w)
     48 {
     49     e[++tot]=(edge){y,head[x],w};head[x]=tot;
     50     e[++tot]=(edge){x,head[y],w};head[y]=tot;
     51 }
     52 inline void getrt(int x,int fa)
     53 {
     54    s[x]=1;ss[x]=0;
     55    for4(i,x)if(!del[y]&&y!=fa)
     56    {
     57          getrt(y,x);
     58          s[x]+=s[y];
     59          ss[x]=max(ss[x],s[y]);
     60    }
     61    ss[x]=max(ss[x],sum-s[x]);
     62    if(ss[x]<ss[rt])rt=x;
     63 }
     64 inline void get(int x,int fa,int w)
     65 {
     66    g[++tot]=w;f[tot][0]=l;f[tot][1]=r;
     67    for4(i,x)if(!del[y]&&y!=fa)get(y,x,w+e[i].w);
     68 }
     69 inline void solve(int x)
     70 {
     71    del[x]=1;
     72    l=r=++tot;
     73    for4(i,x)if(!del[y])get(y,x,e[i].w),r=tot;
     74    for4(i,x)if(!del[y]){sum=s[y];rt=0;getrt(y,x);solve(rt);}
     75 }
     76 inline int query(int x,int y)
     77 {
     78    int t=log2(y-x+1),t1=mx[x][t],t2=mx[y-(1<<t)+1][t];
     79    return g[t1]>g[t2]?t1:t2;
     80 }
     81 int main()
     82 {
     83    freopen("input.txt","r",stdin);
     84    freopen("output.txt","w",stdout);
     85    n=read();m=read();
     86    for1(i,n-1){int x=read(),y=read();add(x,y,read());}
     87    tot=0;sum=n;
     88    ss[rt=0]=inf;
     89    getrt(1,0);
     90    solve(rt);
     91    for1(i,tot)mx[i][0]=i;
     92    for1(i,20)
     93     for1(j,tot-(1<<i)+1)
     94      {
     95          int t1=mx[j][i-1],t2=mx[j+(1<<(i-1))][i-1];
     96          mx[j][i]=g[t1]>g[t2]?t1:t2;
     97      }
     98    for1(i,tot)q.push((rec){f[i][0],f[i][1],i,query(f[i][0],f[i][1])});
     99    while(m--)
    100    {
    101         rec t=q.top();q.pop();
    102         printf("%d
    ",g[t.x]+g[t.y]);
    103       if(t.y+1<=t.r)q.push((rec){t.y+1,t.r,t.x,query(t.y+1,t.r)});
    104       if(t.y-1>=t.l)q.push((rec){t.l,t.y-1,t.x,query(t.l,t.y-1)});
    105    }
    106    return 0;
    107 }
    View Code
  • 相关阅读:
    android Json解析详解
    Android 用ping的方法判断当前网络是否可用
    Android 监控网络状态
    Android TableLayout 常用的属性介绍及演示
    三星笔记本R428安装xp win7双系统,切换系统重启才能进入系统解决办法。
    解决Win8不能上网攻略第二版!三步秒杀原驱动
    Android三种实现自定义ProgressBar的方式介绍
    Android应用开发中半透明效果实现方案
    FFT算法的物理意义
    网络编程Socket之TCP之close/shutdown具体解释(续)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4364492.html
Copyright © 2020-2023  润新知