ZOJ3261-Connections in Galaxy War-(逆向并查集+离线处理)
题意:
1.有n个星球,每个星球有一个编号(1-n)和一个能量值。
2.一开始将某些星球连通。
3.开战后有很多个操作,查询某个星球能找谁求救或者摧毁两颗星球之间的连通路径,使其不能连通。如果连通则可以相互求救,求救的对象要求能量比自己大并且在连通的星球中能量最大,如果能量最大的星球有多个,则找编号小的。
解题:
1.用并查集连通星球,把能量大的作为根节点,如果能量相同则把编号小的作为根节点,方便查询求救对象。
2.并查集没有断开的操作,把末态作为起始状态逆推。保存一开始的连通路径和开战后摧毁的连通路径,战争结束的状态作为起始状态,不连通被摧毁的连通路径。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std; int n,m,x,y,q;
int par[];///父亲
map<int,bool>mp;
int ans[];
struct star
{
int id;///编号
int val;///能量值
};star s[]; struct edge
{
int x;
int y;
};edge e[]; struct query
{
char s[];
int x,y; };query que[]; int find(int a)
{
if( par[a]==a )
return a;
return par[a]=find(par[a]);
} void unit(int a,int b)
{
int aa=find(a);
int bb=find(b);
if(aa!=bb)
{
if( s[aa].val==s[bb].val )///相同能量值
{
if( s[aa].id<s[bb].id )///编号小的做根节点
par[bb]=aa;
else
par[aa]=bb;
}
else if( s[aa].val<s[bb].val )///能量值大的作为根节点
par[aa]=bb;
else
par[bb]=aa;
}
} int main()
{
bool first=true;
while(scanf("%d",&n)!=EOF)///行星数量
{
if(first)///第一次进来变为false,以后每次都要打印空行
first=false;
else printf("\n");
mp.clear();
memset(ans,inf,sizeof(ans));
for(int i=;i<n;i++)///能量值
{
scanf("%d",&s[i].val);
s[i].id=i;
par[i]=i;
}
scanf("%d",&m);///连通边
for(int i=;i<m;i++)
{
scanf("%d%d",&x,&y);
if(x>y)///保证x<y
swap(x,y);
e[i].x=x;
e[i].y=y;///存连通边
mp[ x*+y ]=false;///没被毁掉
}
scanf("%d",&q);///查询
for(int i=;i<q;i++)
{
getchar();
scanf("%s",que[i].s);
if(que[i].s[]=='q')
scanf("%d",&que[i].x);
else
{
scanf("%d %d",&x,&y);
if(x>y)///保证x<y
swap(x,y);
que[i].x=x;
que[i].y=y;
mp[ x*+y ]=true;///被毁掉
}
}
///离线处理
for(int i=;i<m;i++)///把没被毁掉的边的末态作为起始态,逆推
{
x=e[i].x;
y=e[i].y;
if( !mp[ x*+y ] )
unit(x,y);
}
///逆推,保存对应的答案
for(int i=q-;i>=;i--)
{
if( que[i].s[]=='q' )
{
x=find(que[i].x);///连通星球中 能量最大的 根星球
if( s[x].val>s[ que[i].x ].val )
ans[i]=s[x].id;
else
ans[i]=-;
}
else
unit( que[i].x,que[i].y );
}
///顺序输出答案
for(int i=;i<q;i++)
{
if(ans[i]!=inf)
printf("%d\n",ans[i]);
}
}
return ;
}
ZOJ3261-Connections in Galaxy War-(逆向并查集+离线处理)的更多相关文章
- 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 In order to strengthen the defense ability, many stars in galaxy allied to ...
- Connections in Galaxy War(逆向并查集)
Connections in Galaxy War http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3563 Time Limit ...
- ZOJ 3261 Connections in Galaxy War(逆向并查集)
参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...
- ZOJ3261 Connections in Galaxy War —— 反向并查集
题目链接:https://vjudge.net/problem/ZOJ-3261 In order to strengthen the defense ability, many stars in g ...
- 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为切断 ...
随机推荐
- C# Convert.ChangeType()
Convert.ChangeType() 将未知类型转换为已知类型 ; object result = Convert.ChangeType(content, typeof(int)); 其他常用的转 ...
- 第二节:EF Core的常规“增删改”及状态的变化
一. 整体说明 1. 本节用到的表 2. 状态说明补充 ①.Detached: 游离的状态,与数据库没有什么交涉,比如新new一个实体,状态就是Detached. ②.Added: 增加的状态. ③. ...
- 【转】Mac入门(一)基本用法
我前五年一直外包到微软,每天使用的都是Windows系统和.NET. 2012年加入VMware, 公司的工作机是台Mac 笔记本(MacBook Pro), 所以有机会接触Mac系统 Mac和Wi ...
- 通过Queue控制线程并发,并监控队列执行进度
# -*- coding:utf-8 -*- import Queue import time import threading # 需要执行的业务主体 def domain(id): time.sl ...
- [SOJ #721]第三送分题(2019-11-14考试)/[CF675E]Trains and Statistic
题目大意 在一条直线上有\(n\)个点.在第\(i\)个点可以花费\(1\)的代价到达\((i,a_i]\)中任意一点,用\(S[i][j]\)表示从点\(i\)到点\(j\)的最少花费,求\(\su ...
- Linux学习笔记之文件读取过程
0x00 概述 对于Linux系统来说,一切的数据都起源于磁盘中存储的文件.Linux文件系统的结构及其在磁盘中是如何存储的?操作系统是怎样找到这些文件进行读取的?这一章主要围绕这几个问题进行介绍(以 ...
- java基础 super和this
/** * super关键字的用法有三种: * 1.在子类的成员方法中,访问父类的成员变量 * 2.在子类的成员方法中,访问父类的成员方法 * 3.在子类的构造方法中,访问父类的构造方法 * * th ...
- 类再生(合成、继承、final)
类再生 有两种方法达到代码复用的效果:合成.继承. 合成的语法 合成就是形成对象,把复用的代码置入对象句柄. 在类内字段使用基本数据会初始化为零,但对象句柄会初始化为null.在下面的程序中若没有ne ...
- Git教程-安装与创建版本库
Git是一个分布式版本控制系统,他通过命令行使用的工具,Github是提供Git仓库托管服务的网站 安装参考: https://www.liaoxuefeng.com/wiki/89604348802 ...
- 异常---Day21(写得有错请指出,感谢)
异常的概念 异常,就是不正常的意思.在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是:指的是程序在执行过程中,出现的非正常的情况,终会导致J ...