ZOJ 3261 Connections in Galaxy War(逆向并查集)
参考链接:
http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html
http://blog.csdn.net/roney_win/article/details/9473225
题意:N个星球,编号从0到N-1。每个星球有一个战斗力power,且这N个星球之间建有一些通道,可以相互联系,在星球大战中,一些星球要向和自己联通的星球中power最强且大于自己的星球求救,且在星球大战中会有一些通道被损坏。
两种操作:破坏a和b之间的通道;a星球该向谁求救。
逆向并查集:
与并查集不同,给出一个图中原有的一些边,然后给出操作,操作不是向图中添加边,而是在已有的边上,将边删除。
对于该种情况,需要首先读入所有操作,把要求删除的边全部删除,再按照从后往前的顺序处理操作,这样删边操作转化为了添边的操作。
思路:我们先输入所有数据,即所谓的离线输入,将星球大战之后的状态作为初始状态,进行并查集的操作,遇到destroy时,就恢复a到b之间的通道,那么就很容易维护根节点的性质了,这题就变得很简单了。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm> using namespace std; const int maxn=;
int father[maxn];
long long power[maxn];
int n,m,q;
int ans[maxn*]; //存储最后要输出的答案 struct Edge{
int u,v,flag; //u、v表示边的端点,u<=v;flag=0表示改变被删除 //将u从小到大排序,若u相同时,按v从小到大排序
bool operator < (const Edge tmp)const {
if(u==tmp.u)
return v<tmp.v;
return u<tmp.u;
}
} edge[*maxn]; //先把所有的询问都存储下来
struct Query{
int k,a,b; //k=1表示操作是询问,k=2表示操作是删边
}query[maxn*]; struct Node {
int u; //u代表集合中具有最大能力值的点的编号
long p; //p代表集合中点的最大能力值
} node[maxn]; void init() {
for(int i=; i<n; i++) {
father[i]=i;
node[i].u=i;
node[i].p=power[i];
}
} int find_root(int x) {
if(father[x]!=x)
father[x]=find_root(father[x]);
return father[x];
} void Union(int x,int y) {
father[y]=x;
if(node[x].p<node[y].p){
node[x].p=node[y].p;
node[x].u=node[y].u;
}
else if(node[x].p==node[y].p && node[x].u>node[y].u){
node[x].u=node[y].u;
}
}
//二分查找边,a<=b
void findEdge(int a,int b){
int mid,mins=,maxs=m-;
while(mins<=maxs){
mid=(mins+maxs)>>;
if(a==edge[mid].u && b==edge[mid].v){
edge[mid].flag=;
return;
}
if(a<edge[mid].u){
maxs=mid-;
}
else if(a>edge[mid].u){
mins=mid+;
}
else{
if(b<edge[mid].v){
maxs=mid-;
}
else{
mins=mid+;
}
}
}
}
int main() {
int a,b,blank=;
char ch[];
while(scanf("%d",&n)!=EOF) {
memset(vis,,sizeof(vis));
if(blank==)
blank=;
else
puts("");
for(int i=;i<n;i++){
scanf("%I64d",&power[i]);
}
scanf("%d",&m);
for(int i=; i<m; i++) {
scanf("%d%d",&a,&b);
if(a<b) {
edge[i].u=a;
edge[i].v=b;
edge[i].flag=;
} else {
edge[i].u=b;
edge[i].v=a;
edge[i].flag=;
}
}
sort(edge,edge+m); //一开始忘记排序了
scanf("%d",&q);
for(int i=; i<q; i++) {
scanf("%s",ch);
if(ch[]=='q') {
scanf("%d",&a);
query[i].k=;
query[i].a=a;
query[i].b=-;
}
else{
scanf("%d%d",&a,&b);
int t;
if(a>b){
t=a;a=b;b=t;
}
findEdge(a,b);
query[i].k=;
query[i].a=a;
query[i].b=b;
}
}
int x,y;
init();
for(int i=;i<m;i++){
if(edge[i].flag==){
x=find_root(edge[i].u);
y=find_root(edge[i].v);
if(x!=y){
Union(x,y);
}
}
}
int u,v;
for(int i=q-;i>=;i--){
if(query[i].k==){
x=find_root(query[i].a);
if(node[x].p>power[query[i].a]){
ans[i]=node[x].u;
}
else{
ans[i]=-;
}
}
else{
u=query[i].a;
v=query[i].b;
x=find_root(u);
y=find_root(v);
if(x!=y){
Union(x,y);
}
ans[i]=-;
}
}
for(int i=;i<q;i++){
if(ans[i]==-)
continue;
printf("%d\n",ans[i]);
}
}
return ;
}
ZOJ 3261 Connections in Galaxy War(逆向并查集)的更多相关文章
- zoj 3261 Connections in Galaxy War(并查集逆向加边)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...
- ZOJ 3261 - Connections in Galaxy War ,并查集删边
In order to strengthen the defense ability, many stars in galaxy allied together and built many bidi ...
- ZOJ - 3261 Connections in Galaxy War(并查集删边)
https://cn.vjudge.net/problem/ZOJ-3261 题意 银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可 ...
- ZOJ 3261 Connections in Galaxy War (逆向+带权并查集)
题意:有N个星球,每个星球有自己的武力值.星球之间有M条无向边,连通的两个点可以相互呼叫支援,前提是对方的武力值要大于自己.当武力值最大的伙伴有多个时,选择编号最小的.有Q次操作,destroy为切断 ...
- Connections in Galaxy War (逆向并查集)题解
Connections in Galaxy War In order to strengthen the defense ability, many stars in galaxy allied to ...
- ZOJ3261:Connections in Galaxy War(逆向并查集)
Connections in Galaxy War Time Limit: 3 Seconds Memory Limit: 32768 KB 题目链接:http://acm.zju.edu. ...
- Connections in Galaxy War(逆向并查集)
Connections in Galaxy War http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3563 Time Limit ...
- 洛谷 P1197 BZOJ 1015 [JSOI2008]星球大战 (ZOJ 3261 Connections in Galaxy War)
这两道题长得差不多,都有分裂集合的操作,都是先将所有操作离线,然后从最后一步开始倒着模拟,这样一来,分裂就变成合并,也就是从打击以后最终的零散状态,一步步合并,回到最开始所有星球都被连为一个整体的状态 ...
- zoj 3261 Connections in Galaxy War
点击打开链接zoj 3261 思路: 带权并查集 分析: 1 题目说的是有n个星球0~n-1,每个星球都有一个战斗值.n个星球之间有一些联系,并且n个星球之间会有互相伤害 2 根本没有思路的题,看了网 ...
随机推荐
- GNU Binutils工具
参考<程序员的自我修养---连接.装载与库> 以下内容转贴自 http://www.cnblogs.com/xuxm2007/archive/2013/02/21/2920890.html ...
- Win7在CMD命令行中使用管理员权限运行命令
使用命令: runas /user:administrator 需要执行的命令 如下:
- UDP HelloWord
Client.cpp #include <stdio.h> #include <winsock2.h> #pragma comment (lib,"ws2_32&qu ...
- vim命令总结
前言 本文翻译自:http://bencrowder.net/files/vim-fu/,参考了VIM中文帮助. Google翻译结果和实际操作结果,对原文的部分内容重新整理,删除和添加了 部分内容并 ...
- MS MQ 消息队列
一.安装 先在 控制面板—程序和功能—打开或关闭我windows功能.把 msmq全勾起来 如下图: 二.右击-消息对列—属性—服务器安全性,把禁用未经身份验证的RPC调用勾去掉, 三.然后在专用队列 ...
- linux下bus,device,driver三者关系
linux下bus,device,driver三者关系 1.bus: 总线作为主机和外设的连接通道,有些总线是比较规范的,形成了很多协议.如 PCI,USB,1394,IIC等.任何设备都可以选择合适 ...
- PIGCMS提示“你的程序为盗版,非法授权,请联系QQ7530782或者8441010”的修复方法
最近群里又有人发出来微信平台盗版源码这个问题求解决,其实我本人是一直支持正版的,大家有条件的还是购买正好为好,既然有人问我就顺便解决了下,其实很简单,再换个接口就好了,查看了一下是在\PigCms\L ...
- 34 个使用 Raspberry Pi 的酷创意
如果你手头有一个 Raspberry Pi(树莓派),你会拿它来做什么?或许以下 34 个如何使用 Raspberry Pi 的创意能够给你带来一些启发. Web 服务器 家庭自动化 BitTorre ...
- (C学习基础)一,CMD的使用
以后考研要考数据结构,所以系统的整理一下C学习笔记.这里开发用VS2013 CMD资料在这里下载 首先就是DOS系统的CMD的使用,是不是觉得会命令行语句的人特别牛呢,有时候使用命令行总是事半功倍, ...
- iOS 进阶 第十一天(0411)
0411 UItaBbar的结构 每一个数组都有一个方法,那就是下面这个,如下图所示: 如果想看系统控件是怎么构成的,那么就采用遍历其子控件的方式来做,如上一图中所示 在iOS7及其以后的系统里,控制 ...