题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现在发生战争,有一些联系通道会被摧毁,而一些星球会通过还没有被摧毁的联系通道直接或者间接联系能够联系到的武力值最高的星球求救,如果有多个武力值都为最高的,那就联系一个编号最小的。现在给出一系列求救和摧毁的序列,一次执行,并对于每一个求救指令寻找合适的求救星球编号,如果没有可以求救的则输出 -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. [转]Android进程与线程基本知识

    转自:http://www.cnblogs.com/hanyonglu/archive/2012/04/12/2443262.html 本文介绍Android平台中进程与线程的基本知识. 很早的时候就 ...

  2. python3控制路由器--使用requests重启极路由.py

    代码写了相应的注释,以后再写成可以方便调用的模块. 用fiddler抓包可以看到很多HTTP头,经过尝试发现不是都必须的. 'Upgrade-Insecure-Requests':1,#必要项,值为1 ...

  3. IOS 设置透明度导致底层View始终可见

    正确效果如图:下面的toolBar应该看不见它下面的View, 避免方法:[self.view  addSubView:aSubView];这个aSubView一定不能设置不透明度,应将其设置为Cle ...

  4. Javascript---数组常用方法

    一.concat(); 连接两个数组,并返回结果 var arr = new Array(3) arr[0] = "George" arr[1] = "John" ...

  5. 知道创宇研发技能表v2.2

    知道创宇研发技能表v2.2 2014/3/9 发布 by @知道创宇(www.knownsec.com) @余弦 & 行之 知道创宇是国内Geek十足且普遍被认为特别有前途的互联网安全公司, ...

  6. hdu 2056

    ps:    - -惭愧...是套用一个大神的计算方法来做的.....下面是代码 代码: #include "stdio.h"#include "stdlib.h&quo ...

  7. A​n​d​r​o​i​d​ ​B​l​u​e​t​o​o​t​h​详​解(Android英文文档相关译文)

    一.Bluetooth Android平台包含了对Bluetooth协议栈的支持,允许机器通过Bluetooth设备进行无线数据交换.应用框架通过Android Bluetooth API访问Blue ...

  8. 转载 javascript中的正则表达式总结 二

    学习正则表达式 今年的第一篇javascript文章就是这个正则表达式了,之前的文章是转载别人的,不算自己的东西,可以忽略不计,最近突然想把转载别人的东西 统统删掉,因为转载过的文章,我根本没有从中获 ...

  9. convert转化成特定日期格式

    CONVERT() 函数可以用不同的格式显示日期/时间数据. CONVERT(data_type(length),data_to_be_converted,style) 例子: CONVERT(VAR ...

  10. Day09_面向对象第四天

    1.多态的概念和前提(掌握) 1.概念-什么是多态(掌握)       对象在不同时刻表现出来的不同状态.   2.针对引用类型的理解 编译期间状态和运行期间状态不一样      比如        ...