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行,由于按这个方法写,上移过程中,当前点不会被更新进已有答案
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct E1
{
int a,b,w;
friend bool operator<(const E1& a,const E1& b)
{
return a.w>b.w;
}
}e1[];
struct Edge
{
int to,d,nxt;
}e[];
int fa[],p[],n,m,ne,f1[],log2n,deep[],q,ans1;
int minn[][],maxn[][],minans[][],maxans[][],anc[][];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void dfs(int x,int fa)
{
int i,k;
minn[x][]=maxn[x][]=p[x];
//minans[x][0]=maxans[x][0]=0;
for(i=;i<=log2n;i++)
{
anc[x][i]=anc[anc[x][i-]][i-];
minn[x][i]=min(minn[x][i-],minn[anc[x][i-]][i-]);
maxn[x][i]=max(maxn[x][i-],maxn[anc[x][i-]][i-]);
minans[x][i]=max(max(minans[anc[x][i-]][i-],minans[x][i-]),maxn[x][i-]-minn[anc[x][i-]][i-]);
maxans[x][i]=max(max(maxans[anc[x][i-]][i-],maxans[x][i-]),maxn[anc[x][i-]][i-]-minn[x][i-]);
}
for(k=f1[x];k!=;k=e[k].nxt)
if(e[k].to!=fa)
{
deep[e[k].to]=deep[x]+;
anc[e[k].to][]=x;
dfs(e[k].to,x);
}
}
int get(int x,int y)
{
//if(deep[x]<deep[y]) swap(x,y);
int t,i,ansx=,ansy=,minx=p[x],maxy=p[y];
for(t=deep[x]-deep[y],i=;t>;t>>=,i++)
if(t&)
{
ansx=max(ansx,max(maxans[x][i],maxn[x][i]-minx));
minx=min(minx,minn[x][i]);
x=anc[x][i];
}
for(t=deep[y]-deep[x],i=;t>;t>>=,i++)
if(t&)
{
ansy=max(ansy,max(minans[y][i],maxy-minn[y][i]));
maxy=max(maxy,maxn[y][i]);
y=anc[y][i];
}
if(x==y)
return max(max(ansx,ansy),maxy-minx);
for(i=log2n;i>=;i--)
if(anc[x][i]!=anc[y][i])
{
ansx=max(ansx,max(maxans[x][i],maxn[x][i]-minx));
minx=min(minx,minn[x][i]);
ansy=max(ansy,max(minans[y][i],maxy-minn[y][i]));
maxy=max(maxy,maxn[y][i]);
x=anc[x][i];
y=anc[y][i];
}
ansx=max(ansx,max(maxans[x][],maxn[x][]-minx));
minx=min(minx,minn[x][]);
ansy=max(ansy,max(minans[y][],maxy-minn[y][]));
maxy=max(maxy,maxn[y][]);
return max(max(max(ansx,ansy),maxy-minx),max(p[anc[x][]]-minx,maxy-p[anc[y][]]));
}
int main()
{
int i,t1,t2,a,b;
while(scanf("%d",&n)==)
{
log2n=log2(n);
ne=;ans1=;
memset(f1,,sizeof(f1));
memset(minn,0x3f,sizeof(minn));
memset(maxn,,sizeof(maxn));
memset(minans,,sizeof(minans));
memset(maxans,,sizeof(maxans));
for(i=;i<=n;i++)
scanf("%d",&p[i]);
scanf("%d",&m);
for(i=;i<=m;i++)
scanf("%d%d%d",&e1[i].a,&e1[i].b,&e1[i].w);
sort(e1+,e1+m+);
for(i=;i<=n;i++)
fa[i]=i;
for(i=;i<=m;i++)
{
t1=find(e1[i].a);
t2=find(e1[i].b);
if(t1==t2) continue;
e[++ne].to=e1[i].b;
e[ne].nxt=f1[e1[i].a];
e[ne].d=e1[i].w;
f1[e1[i].a]=ne;
e[++ne].to=e1[i].a;
e[ne].nxt=f1[e1[i].b];
e[ne].d=e1[i].w;
f1[e1[i].b]=ne;
fa[t1]=t2;
ans1+=e1[i].w;
}
printf("%d\n",ans1);
dfs(,);
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&a,&b);
printf("%d\n",get(a,b));
}
}
return ;
}
Social Net ZOJ - 3649的更多相关文章
- ZOJ - 3649 树上倍增
题意:给出一个图,先求出最大生成树,然后多次询问树上路径\(u→v\)的有向最大极差\(max(a_i-a_j),i>j\),其中\(i\)和\(j\)指代节点在路径中出现的顺序 极差具有单调性 ...
- zoj 3649 lca与倍增dp
参考:http://www.xuebuyuan.com/609502.html 先说题意: 给出一幅图,求最大生成树,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的 ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- ZOJ People Counting
第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ 3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...
- 讲座:Influence maximization on big social graph
Influence maximization on big social graph Fanju PPT链接: social influence booming of online social ne ...
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- Call for Papers IEEE/ACM International Conference on Advances in Social Network Analysis and Mining (ASONAM)
IEEE/ACM International Conference on Advances in Social Network Analysis and Mining (ASONAM) 2014 In ...
- ZOJ Problem Set - 1394 Polar Explorer
这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...
- ZOJ Problem Set - 1392 The Hardest Problem Ever
放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...
随机推荐
- mysql关闭skip-grant-tables快速重置mysql密码
如果你忘记了mysql密码几乎是没有什么好办法可以直接修改密码了,但我们可以在my.ini把加上skip-grant-tables,然后重启mysql就不需要密码了,这时我们再修改root密码,最后再 ...
- Codeforces Round #253 (Div. 2)——Borya and Hanabi
题目连接 题意: n表示有n个卡片.每一个卡片有一种颜色和一个数字(共五种不同的颜色和五个不同的数字). 事先知道每种卡片有几张.可是不知道详细的位置. 问须要几次提示就能够知道全部卡片的位置都在哪里 ...
- vc++6.0中右键点击"转到定义"为什么是"未定义符号"呢?
VC的问题,需要生成一下浏览信息...然后rebuild
- Tomcat安全配置规范
第1章 账号管理.认证授权 1.1 账号 1.1.1 共享帐号管理 安全基线项目名称 Tomcat共享帐号管理安全基线要求项 安全基线编号 SBL-Tomcat-01-01-01 安全基线项说明 ...
- 防sql注入 盲注等措施 ESAPI的使用
SQL注入往往是在程序员编写包含用户输入的动态数据库查询时产生的,但其实防范SQL注入的方法非常简单.程序员只要a)不再写动态查询,或b)防止用户输入包含能够破坏查询逻辑的恶意SQL语句,就能够防范S ...
- yum下载对应内核版本的kernel-devel
1 查看内核版本 uname -r 2 查看目前已有的kernel-devel uname -a ; rpm -qa kernel\* | sort 3 下载对应版本 $ sudo yum insta ...
- (C)理解#define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
理解 #define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) 嵌入式系统编程,要求程序员能够利用C语言访问固 ...
- JavaScript数组遍历:for、foreach、for in、for of、$.each、$().each的区别
一.for Javascript中的for循环,它用来遍历数组 var arr = [1,2,3,4] for(var i = 0 ; i< arr.length ; i++){ console ...
- HDU1358 Period —— KMP 最小循环节
题目链接:https://vjudge.net/problem/HDU-1358 Period Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...
- YTU 2878: 结构体--学生信息排序
2878: 结构体--学生信息排序 时间限制: 1 Sec 内存限制: 128 MB 提交: 297 解决: 148 题目描述 定义存放一个学生信息的结构体类型,学生信息包括:姓名,学号,性别,院 ...