标签:html 最大值 ons 就是 tor 查询 ref problem 操作
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
$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 2 #include 3 #include 4 #include
5 using namespace std;
6 struct E1
7 {
8 int a,b,w;
9 friend bool operatorconst 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)
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] 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)
94 scanf("%d",&p[i]);
95 scanf("%d",&m);
96 for(i=1;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)
100 fa[i]=i;
101 for(i=1;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\n",ans1);
118 dfs(1,0);
119 scanf("%d",&q);
120 while(q--)
121 {
122 scanf("%d%d",&a,&b);
123 printf("%d\n",get(a,b));
124 }
125 }
126 return 0;
127 }
Social Net ZOJ - 3649
标签:html 最大值 ons 就是 tor 查询 ref problem 操作
原文地址:http://www.cnblogs.com/hehe54321/p/zoj-3649.html