题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现在发生战争,有一些联系通道会被摧毁,而一些星球会通过还没有被摧毁的联系通道直接或者间接联系能够联系到的武力值最高的星球求救,如果有多个武力值都为最高的,那就联系一个编号最小的。现在给出一系列求救和摧毁的序列,一次执行,并对于每一个求救指令寻找合适的求救星球编号,如果没有可以求救的则输出 -1;

由于一般并查集只能够合并集合而不能将集合拆离,因此可以离线之后反向执行,这样集合的拆离就变成了集合的合并。

只要先保存所有的边和询问,然后对于所有的摧毁联系用建边的方式记录,然后扫一遍一开始的联系通道关系,除了将会被摧毁的边不动外,将剩下的联系通道用并查集的方式建立起来。

由于需要查找的值是武力值最大并且编号最小的,所以可以在合并并查集的时候根据武力值大小,将武力值小的那个节点的父亲设置为祖先大的,如果需要合并的两个节点的武力值是相等的,那么把编号大的节点的父亲设置为编号小的节点,这样在查询祖先的时候就一定查到武力值最大并且编号最小的节点了。

然后对于所有命令序列反向处理,从最后一条开始,查询就直接输出结果,如果查到的祖先节点是它自己就输出 -1,如果是摧毁通道那就建立这两点之间的通道就行了。

 #include<stdio.h>
#include<string.h> int fa[],n,a[],ans[];
int l1[],l2[],y[],z[];
bool x[];
int head[],nxt[],point[],size;
char s[]; void add(int a,int b){
point[size]=b;
nxt[size]=head[a];
head[a]=size++;
point[size]=a;
nxt[size]=head[b];
head[b]=size++;
} int mmax(int a,int b){
return a>b?a:b;
} void init(){
for(int i=;i<n;i++)fa[i]=i;
} int find(int x){
int r=x,t;
while(r!=fa[r])r=fa[r];
while(x!=r){
t=fa[x];
fa[x]=r;
x=t;
}
return r;
} int main(){
int c=;
while(scanf("%d",&n)!=EOF){
if(c++)printf("\n");
int i,m;
size=;
memset(head,-,sizeof(head));
for(i=;i<n;i++)scanf("%d",&a[i]);
init();
scanf("%d",&m);
for(i=;i<=m;i++)scanf("%d%d",&l1[i],&l2[i]);
int q;
scanf("%d",&q);
for(i=;i<=q;i++){
scanf("%s",s);
if(s[]=='q'){
x[i]=;
scanf("%d",&y[i]);
}
else{
x[i]=;
scanf("%d%d",&y[i],&z[i]);
add(y[i],z[i]);
}
}
int j;
bool f;
for(i=;i<=m;i++){
f=;
for(j=head[l1[i]];~j;j=nxt[j]){
if(point[j]==l2[i]){f=;break;}
}
if(!f)continue;
int x1=find(l1[i]),y1=find(l2[i]);
if(x1!=y1){
if(a[x1]>a[y1])fa[y1]=x1;
else if(a[x1]<a[y1])fa[x1]=y1;
else if(x1<y1)fa[y1]=x1;
else fa[x1]=y1;
}
}
int cnt=;
for(i=q;i>=;i--){
if(x[i]){
int x1=find(y[i]),y1=find(z[i]);
if(x1!=y1){
if(a[x1]>a[y1])fa[y1]=x1;
else if(a[x1]<a[y1])fa[x1]=y1;
else if(x1<y1)fa[y1]=x1;
else fa[x1]=y1;
}
}
else{
int x1=find(y[i]);
ans[++cnt]=a[x1]>a[y[i]]?x1:-;
}
}
for(i=cnt;i>=;i--){
printf("%d\n",ans[i]);
}
}
return ;
}

zoj3261 带权并查集的更多相关文章

  1. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  2. [NOIP摸你赛]Hzwer的陨石(带权并查集)

    题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...

  3. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  4. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

  5. 【BZOJ-4690】Never Wait For Weights 带权并查集

    4690: Never Wait for Weights Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 88  Solved: 41[Submit][ ...

  6. hdu3038(带权并查集)

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示 ...

  7. 洛谷OJ P1196 银河英雄传说(带权并查集)

    题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...

  8. poj1984 带权并查集

    题意:有多个点,在平面上位于坐标点上,给出一些关系,表示某个点在某个点的正东/西/南/北方向多少距离,然后给出一系列询问,表示在第几个关系给出后询问某两点的曼哈顿距离,或者未知则输出-1. 只要在元素 ...

  9. poj1611 带权并查集

    题意:病毒蔓延,现在有 n 个人,其中 0 号被认为可能感染,然后给出多个社交圈,如果某个社交圈里有人被认为可能被感染,那么所有这个社交圈里的人都被认为可能被感染,现在问有多少人可能被感染. 带权并查 ...

随机推荐

  1. CPU是怎么制造的

    大概的过程就是,先选一堆好沙子(纯净的沙子),初步加工一般在沿海,然而都是初加工,因为技术不行,所以一般用比较污染环境的方法加工大99.9%纯度的硅,然后低价卖给国外企业,用高精尖技术加工到99.99 ...

  2. 【转】clang warning 警告清单(备查,建议直接command + F 速查 )

    Warning Message -WCFString-literal input conversion stopped due to an input byte that does not belon ...

  3. DataNode,NameNode,JobTracker,TaskTracker用jps查看无法启动解决办法

    查看tasktracker的50060的地址无法正常查看,主要有两个原因,一个是在/tmp目录下有以前使用2.02版本留下的文件没有删除,二个是因为端口被占用了 解决方法: 一.删除/tmp目录下所有 ...

  4. VMware-workstation-full-10.0.1-1379776 CN

    从V10版本开始,VMware Workstation 官方自带简体中文了,以后大家不需要汉化啦! 今天,VMware Workstation 10.0.1正式发布,版本号为Build 1379776 ...

  5. [__NSCFString absoluteURL]错误的解决方案

    Xcode提醒错误: -[__NSCFString absoluteURL]: unrecognized selector sent to instance 0x8c4d3a0 *** Termina ...

  6. 在Windows平台搭建PHP开发环境(四)

    一.概念 1.1 在Windows下搭建 wamp: apache(iis) + php + mysql +phpmyadmin 1.2 在Linux下搭建     lamp: linux + php ...

  7. SQLSERVER数据库中批量导入数据的几种方法

    第一:使用Select Into 语句 如果企业数据库都是采用SQL Server数据库的话,则可以利用select into语句实现数据的导入. select into语句的作用是把数据从另外一个数 ...

  8. C杂记

    printf主要是为了便于取地址,默认将char,short变成了int,float变成了double:但scanf的时候,因为数据宽度的问题,必须区分%f和%lf. memset 是字符串操作函数: ...

  9. (转)HTML5开发学习(2):本地存储之localStorage 、sessionStorage、globalStorage

    原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(2):本地存储之localStorage ...

  10. openstack 中 log模块分析

    1 . 所在模块,一般在openstack/common/log.py,其实最主要的还是调用了python中的logging模块: 入口函数在 def setup(product_name, vers ...