zoukankan      html  css  js  c++  java
  • Social Net ZOJ

    Social Net ZOJ - 3649

    题意:

    反正原题题意我是看不懂...

    参考:http://www.cnblogs.com/names-yc/p/4922867.html

    给出一幅图,求最大生成树,输出边权之和,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的权值构成的序列中的极差大小——要求,被减数要在减数的后面,即形成序列{a1,a2…aj …ak…an},求ak-aj (k>=j)的最大值。

    做法:

    首先kruskal求一下最大生成树。然后做倍增dp。

    p[i]表示i号节点的权值

    anc[i][j]表示i号节点的第2^j级祖先

    根据倍增的基本思想,有:

    maxn[i][j]表示从i号节点出发向上走,共走过2^j个节点(包含i号节点),这些节点中点权的最大值

    $maxn[i][0]=p[i]$

    $maxn[i][j]=max(maxn[i][j-1],maxn[anc[i][j-1]][j-1])$

    minn[i][j]表示从i号节点出发向上走,共走过2^j个节点(包含i号节点),这些节点中点权的最小值

    $minn[i][0]=p[i]$

    $minn[i][j]=min(minn[i][j-1],minn[anc[i][j-1]][j-1])$

    maxans[i][j]表示从i号节点出发向上走,共走过2^j个节点(包含i号节点),这些节点的权值按经过顺序构成的序列{a1,a2…aj …ak…an}中,求ak-aj(k>=j)的最大值。

    $maxans[i][0]=0$

    $maxans[i][j]=max(maxans[i][j-1],maxans[anc[i][j-1]][j-1],maxn[anc[i][j-1]][j-1]-minn[i][j-1])$

    其含义为:最大差值要么是在前一半产生,要么在后一半产生,要么就是后一半的最大值减去前一半的最小值。

    minans[i][j]表示从i号节点出发向上走,共走过2^j个节点(包含i号节点),这些节点的权值按经过顺序的构成的序列{a1,a2…aj …ak…an}中,求ak-aj(k<=j)的最大值。(这个数组的名字其实不太对...不要管它)

    $minans[i][0]=0$

    $minans[i][j]=max(minans[i][j-1],minans[anc[i][j-1]][j-1],maxn[i][j-1]-minn[anc[i][j-1]][j-1])$

    其含义为:最大差值要么是在前一半产生,要么在后一半产生,要么就是前一半的最大值减去后一半的最小值。

    以上都可以在dfs过程中完成。

    求结果的过程,也可以视为倍增lca,但是在点“上移”的过程中,要求把移过的部分的答案更新到当前答案上。

    设lca(x,y)=z。从x到y的路径,可以视为x到z,z再到y。那么,答案就是max(x到z路径中最大答案,z到y路径中最大答案,z权值-x到z路径中最小值,z到y路径中最大值-z权值,z到y路径中最大答案-x到z路径中最大答案)。

    在x上移时,上移之后的最大答案就是max(x已经过部分产生的最大答案,将要上移部分的最大值-x已经过部分的最小值,将要上移部分的最大答案(在maxans中取))。

    在y上移时,上移之后的最大答案就是max(y已经过部分产生的最大答案,y已经过部分的最大值-将要上移部分的最小值,将要上移部分的最大答案(在minans中取))。

    错误记录(本地):

    1.由于x和y有顺序,不能写成形如47行

    2.缺少63,64行

    3.缺少75-78行,由于按这个方法写,上移过程中,当前点不会被更新进已有答案

    http://www.xuebuyuan.com/1162519.html
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<algorithm>
      5 using namespace std;
      6 struct E1
      7 {
      8     int a,b,w;
      9     friend bool operator<(const E1& a,const E1& b)
     10     {
     11         return a.w>b.w;
     12     }
     13 }e1[50100];
     14 struct Edge
     15 {
     16     int to,d,nxt;
     17 }e[100100];
     18 int fa[50100],p[50100],n,m,ne,f1[50100],log2n,deep[50100],q,ans1;
     19 int minn[50100][17],maxn[50100][17],minans[50100][17],maxans[50100][17],anc[50100][17];
     20 int find(int x)
     21 {
     22     return fa[x]==x?x:fa[x]=find(fa[x]);
     23 }
     24 void dfs(int x,int fa)
     25 {
     26     int i,k;
     27     minn[x][0]=maxn[x][0]=p[x];
     28     //minans[x][0]=maxans[x][0]=0;
     29     for(i=1;i<=log2n;i++)
     30     {
     31         anc[x][i]=anc[anc[x][i-1]][i-1];
     32         minn[x][i]=min(minn[x][i-1],minn[anc[x][i-1]][i-1]);
     33         maxn[x][i]=max(maxn[x][i-1],maxn[anc[x][i-1]][i-1]);
     34         minans[x][i]=max(max(minans[anc[x][i-1]][i-1],minans[x][i-1]),maxn[x][i-1]-minn[anc[x][i-1]][i-1]);
     35         maxans[x][i]=max(max(maxans[anc[x][i-1]][i-1],maxans[x][i-1]),maxn[anc[x][i-1]][i-1]-minn[x][i-1]);
     36     }
     37     for(k=f1[x];k!=0;k=e[k].nxt)
     38         if(e[k].to!=fa)
     39         {
     40             deep[e[k].to]=deep[x]+1;
     41             anc[e[k].to][0]=x;
     42             dfs(e[k].to,x);
     43         }
     44 }
     45 int get(int x,int y)
     46 {
     47     //if(deep[x]<deep[y])    swap(x,y);
     48     int t,i,ansx=0,ansy=0,minx=p[x],maxy=p[y];
     49     for(t=deep[x]-deep[y],i=0;t>0;t>>=1,i++)
     50         if(t&1)
     51         {
     52             ansx=max(ansx,max(maxans[x][i],maxn[x][i]-minx));
     53             minx=min(minx,minn[x][i]);
     54             x=anc[x][i];
     55         }
     56     for(t=deep[y]-deep[x],i=0;t>0;t>>=1,i++)
     57         if(t&1)
     58         {
     59             ansy=max(ansy,max(minans[y][i],maxy-minn[y][i]));
     60             maxy=max(maxy,maxn[y][i]);
     61             y=anc[y][i];
     62         }
     63     if(x==y)
     64         return max(max(ansx,ansy),maxy-minx);
     65     for(i=log2n;i>=0;i--)
     66         if(anc[x][i]!=anc[y][i])
     67         {
     68             ansx=max(ansx,max(maxans[x][i],maxn[x][i]-minx));
     69             minx=min(minx,minn[x][i]);
     70             ansy=max(ansy,max(minans[y][i],maxy-minn[y][i]));
     71             maxy=max(maxy,maxn[y][i]);
     72             x=anc[x][i];
     73             y=anc[y][i];
     74         }
     75     ansx=max(ansx,max(maxans[x][0],maxn[x][0]-minx));
     76     minx=min(minx,minn[x][0]);
     77     ansy=max(ansy,max(minans[y][0],maxy-minn[y][0]));
     78     maxy=max(maxy,maxn[y][0]);
     79     return max(max(max(ansx,ansy),maxy-minx),max(p[anc[x][0]]-minx,maxy-p[anc[y][0]]));
     80 }
     81 int main()
     82 {
     83     int i,t1,t2,a,b;
     84     while(scanf("%d",&n)==1)
     85     {
     86         log2n=log2(n);
     87         ne=0;ans1=0;
     88         memset(f1,0,sizeof(f1));
     89         memset(minn,0x3f,sizeof(minn));
     90         memset(maxn,0,sizeof(maxn));
     91         memset(minans,0,sizeof(minans));
     92         memset(maxans,0,sizeof(maxans));
     93         for(i=1;i<=n;i++)
     94             scanf("%d",&p[i]);
     95         scanf("%d",&m);
     96         for(i=1;i<=m;i++)
     97             scanf("%d%d%d",&e1[i].a,&e1[i].b,&e1[i].w);
     98         sort(e1+1,e1+m+1);
     99         for(i=1;i<=n;i++)
    100             fa[i]=i;
    101         for(i=1;i<=m;i++)
    102         {
    103             t1=find(e1[i].a);
    104             t2=find(e1[i].b);
    105             if(t1==t2)    continue;
    106             e[++ne].to=e1[i].b;
    107             e[ne].nxt=f1[e1[i].a];
    108             e[ne].d=e1[i].w;
    109             f1[e1[i].a]=ne;
    110             e[++ne].to=e1[i].a;
    111             e[ne].nxt=f1[e1[i].b];
    112             e[ne].d=e1[i].w;
    113             f1[e1[i].b]=ne;
    114             fa[t1]=t2;
    115             ans1+=e1[i].w;
    116         }
    117         printf("%d
    ",ans1);
    118         dfs(1,0);
    119         scanf("%d",&q);
    120         while(q--)
    121         {
    122             scanf("%d%d",&a,&b);
    123             printf("%d
    ",get(a,b));
    124         }
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    Python方法
    Cpp求PI
    Asp.net身份验证和授权
    [转] 魔兽系列事件报道
    directxsdk aug 2006
    [转]转变的开始!NVIDIA更换新Logo
    wxWidgets 2.7.0 released
    OpenGL 和 Vista(续)
    暴雪员工的跳槽纪录
    3D版的星际争霸
  • 原文地址:https://www.cnblogs.com/hehe54321/p/zoj-3649.html
Copyright © 2011-2022 走看看