题意:

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-(逆向并查集+离线处理)的更多相关文章

  1. ZOJ3261:Connections in Galaxy War(逆向并查集)

    Connections in Galaxy War Time Limit: 3 Seconds      Memory Limit: 32768 KB 题目链接:http://acm.zju.edu. ...

  2. Connections in Galaxy War (逆向并查集)题解

    Connections in Galaxy War In order to strengthen the defense ability, many stars in galaxy allied to ...

  3. Connections in Galaxy War(逆向并查集)

    Connections in Galaxy War http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3563 Time Limit ...

  4. ZOJ 3261 Connections in Galaxy War(逆向并查集)

    参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...

  5. ZOJ3261 Connections in Galaxy War —— 反向并查集

    题目链接:https://vjudge.net/problem/ZOJ-3261 In order to strengthen the defense ability, many stars in g ...

  6. zoj 3261 Connections in Galaxy War(并查集逆向加边)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...

  7. ZOJ 3261 - Connections in Galaxy War ,并查集删边

    In order to strengthen the defense ability, many stars in galaxy allied together and built many bidi ...

  8. ZOJ - 3261 Connections in Galaxy War(并查集删边)

    https://cn.vjudge.net/problem/ZOJ-3261 题意 银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可 ...

  9. ZOJ 3261 Connections in Galaxy War (逆向+带权并查集)

    题意:有N个星球,每个星球有自己的武力值.星球之间有M条无向边,连通的两个点可以相互呼叫支援,前提是对方的武力值要大于自己.当武力值最大的伙伴有多个时,选择编号最小的.有Q次操作,destroy为切断 ...

随机推荐

  1. C# Convert.ChangeType()

    Convert.ChangeType() 将未知类型转换为已知类型 ; object result = Convert.ChangeType(content, typeof(int)); 其他常用的转 ...

  2. 第二节:EF Core的常规“增删改”及状态的变化

    一. 整体说明 1. 本节用到的表 2. 状态说明补充 ①.Detached: 游离的状态,与数据库没有什么交涉,比如新new一个实体,状态就是Detached. ②.Added: 增加的状态. ③. ...

  3. 【转】Mac入门(一)基本用法

    我前五年一直外包到微软,每天使用的都是Windows系统和.NET. 2012年加入VMware,  公司的工作机是台Mac 笔记本(MacBook Pro), 所以有机会接触Mac系统 Mac和Wi ...

  4. 通过Queue控制线程并发,并监控队列执行进度

    # -*- coding:utf-8 -*- import Queue import time import threading # 需要执行的业务主体 def domain(id): time.sl ...

  5. [SOJ #721]第三送分题(2019-11-14考试)/[CF675E]Trains and Statistic

    题目大意 在一条直线上有\(n\)个点.在第\(i\)个点可以花费\(1\)的代价到达\((i,a_i]\)中任意一点,用\(S[i][j]\)表示从点\(i\)到点\(j\)的最少花费,求\(\su ...

  6. Linux学习笔记之文件读取过程

    0x00 概述 对于Linux系统来说,一切的数据都起源于磁盘中存储的文件.Linux文件系统的结构及其在磁盘中是如何存储的?操作系统是怎样找到这些文件进行读取的?这一章主要围绕这几个问题进行介绍(以 ...

  7. java基础 super和this

    /** * super关键字的用法有三种: * 1.在子类的成员方法中,访问父类的成员变量 * 2.在子类的成员方法中,访问父类的成员方法 * 3.在子类的构造方法中,访问父类的构造方法 * * th ...

  8. 类再生(合成、继承、final)

    类再生 有两种方法达到代码复用的效果:合成.继承. 合成的语法 合成就是形成对象,把复用的代码置入对象句柄. 在类内字段使用基本数据会初始化为零,但对象句柄会初始化为null.在下面的程序中若没有ne ...

  9. Git教程-安装与创建版本库

    Git是一个分布式版本控制系统,他通过命令行使用的工具,Github是提供Git仓库托管服务的网站 安装参考: https://www.liaoxuefeng.com/wiki/89604348802 ...

  10. 异常---Day21(写得有错请指出,感谢)

    异常的概念 异常,就是不正常的意思.在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是:指的是程序在执行过程中,出现的非正常的情况,终会导致J ...