洛谷 P1197 BZOJ 1015 [JSOI2008]星球大战 (ZOJ 3261 Connections in Galaxy War)
这两道题长得差不多,都有分裂集合的操作,都是先将所有操作离线,然后从最后一步开始倒着模拟,这样一来,分裂就变成合并,也就是从打击以后最终的零散状态,一步步合并,回到最开始所有星球都被连为一个整体的状态,这就能套并查集了。中途的询问结果用栈存下来,输出的时候一个个出栈就好
还有一个共同点,都是科幻风格的,都是星际战争,通信都靠隧道,不知道出题人有没有借鉴的意思
假装这篇博客是我刚写完星球大战这题时写的(其实是一年零两个月二十多天以后,写了zoj那题以后写的 2019年01月25日16:35:27)
[JSOI2008]星球大战
题目描述
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系。
某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。
现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
输入输出格式
输入格式:
输入文件第一行包含两个整数,$N (1<=N<=2M)$和$M (1<=M<=200,000)$,分别表示星球的数目和以太隧道的数目。星球用$ 0 ~ N−1 $的整数编号。
接下来的 $M$ 行,每行包括两个整数 $X$, $Y$,其中($0<=X<>Y$ 表示星球 $x$ 和星球 $y$ 之间有 “以太” 隧道,可以直接通讯。
接下来的一行为一个整数 $k$ ,表示将遭受攻击的星球的数目。
接下来的 $k$ 行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这 $k$ 个数互不相同,且都在 $0$ 到$n−1$的范围内。
输出格式:
第一行是开始时星球的连通块个数。接下来的 $k$ 行,每行一个整数,表示经过该次打击后现存星球的连通块个数。
输入输出样例
8 13
0 1
1 6
6 5
5 0
0 6
1 2
2 3
3 4
4 5
7 1
7 2
7 6
3 6
5
1
6
3
5
7
1
1
1
2
3
3
说明
[JSOI2008]
源代码
#include<stdio.h>//当年的一些中文注释的编码坏掉了 int n,m,k;//n??μ?mì?±?k???Y?ù???? int ruin[]={};
bool ru[]={};//ê?·?±??Y?ù
int num=;
int ans[]={},top=; struct Edge{
int next,to;
}e[];
int head[]={},cnt=;//40íò??μ?20íòì??T?ò±?
void add(int u,int v)
{
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt++;
} int fa[];//?ó0?e£?2??ó1?e
int find(int x)
{
return fa[x]==x?x:(fa[x]=find(fa[x]));
}
inline bool uni(int x,int y)
{
x=find(x),y=find(y);
if(x==y) return false;
fa[x]=y;
return true;
} int main()
{
//freopen("test.txt","r",stdin);
for(int i=;i<;i++)
fa[i]=i; scanf("%d%d",&n,&m);
for(int i=,u,v;i<m;i++)
{
scanf("%d%d",&u,&v);
//printf("%d %d %d\n",cnt,u,v);
add(u,v);
//printf("%d %d %d\n\n",cnt,v,u);
add(v,u);
}
scanf("%d",&k);
for(int i=;i<k;i++)
scanf("%d",ruin+i),ru[ruin[i]]=true; num=;
for(int i=;i<n;i++)
{
if(!ru[i])
{
for(int j=head[i];j;j=e[j].next)
{
if(!ru[e[j].to])
uni(i,e[j].to);
}
}
}//í3??è?2??Y?ùoóμ?á?í?·?á?num
for(int i=;i<n;i++)
if(find(i)==i&&!ru[i]) num++;
ans[top++]=num;
//printf("^^^^\n");
for(int i=k-;i>=;i--)
{
ru[ruin[i]]=false;
int u=ruin[i];
int m=/*áùê±í3??áaí?·?á??eê§*/;
for(int j=head[u];j;j=e[j].next)
{
if(!ru[e[j].to])
if(uni(u,e[j].to))
{
m++;
//printf("%d %d ",u,e[j].to);
//printf("%d\n",j);
}
}
num-=m-;
ans[top++]=num;
}
top=k;
while(top>=)
{
printf("%d\n",ans[top]);
top--;
} return ;
}
星球大战
Connections in Galaxy War
Connections in Galaxy War
Time Limit: 3 Seconds Memory Limit: 32768 KB
In order to strengthen the defense ability, many stars in galaxy allied together and built many bidirectional tunnels to exchange messages. However, when the Galaxy War began, some tunnels were destroyed by the monsters from another dimension. Then many problems were raised when some of the stars wanted to seek help from the others.
In the galaxy, the stars are numbered from 0 to N-1 and their power was marked by a non-negative integer pi. When the star A wanted to seek help, it would send the message to the star with the largest power which was connected with star A directly or indirectly. In addition, this star should be more powerful than the star A. If there were more than one star which had the same largest power, then the one with the smallest serial number was chosen. And therefore, sometimes star A couldn't find such star for help.
Given the information of the war and the queries about some particular stars, for each query, please find out whether this star could seek another star for help and which star should be chosen.
Input
There are no more than 20 cases. Process to the end of file.
For each cases, the first line contains an integer N (1 <= N <= 10000), which is the number of stars. The second line contains N integers p0, p1, ... , pn-1 (0 <= pi <= 1000000000), representing the power of the i-th star. Then the third line is a single integer M (0 <= M <= 20000), that is the number of tunnels built before the war. Then M lines follows. Each line has two integers a, b (0 <= a, b <= N - 1, a != b), which means star a and star b has a connection tunnel. It's guaranteed that each connection will only be described once.
In the (M + 2)-th line is an integer Q (0 <= Q <= 50000) which is the number of the information and queries. In the following Q lines, each line will be written in one of next two formats.
"destroy a b" - the connection between star a and star b was destroyed by the monsters. It's guaranteed that the connection between star a and star b was available before the monsters' attack.
"query a" - star a wanted to know which star it should turn to for help
There is a blank line between consecutive cases.
Output
For each query in the input, if there is no star that star a can turn to for help, then output "-1"; otherwise, output the serial number of the chosen star.
Print a blank line between consecutive cases.
Sample Input
2
10 20
1
0 1
5
query 0
query 1
destroy 0 1
query 0
query 1
Sample Output
1
-1
-1
-1
Author: MO, Luyi
Source: ZOJ Monthly, November 2009
源代码
#include<set>
#include<stdio.h>
#include<algorithm> int n,m=-,q; struct Opt{//o==d:a b; o==q: a;
char o;
int a;
int b;
int id;
bool operator < (const Opt & x)const{
return id>x.id;
}
}opt[]; struct Edge{
int s;
int t;
bool operator < (const Edge & x)const{
if(s==x.s) return t<x.t;
return s<x.s;
}
};
std::set<Edge> e;
std::set<Edge>::iterator it;
int ans[]; int p[],mx[],cnt[];
int fa[];
int find(int x)
{
if(fa[x]==x) return x;
fa[x]=find(fa[x]);
cnt[x]=cnt[fa[x]];
mx[x]=mx[fa[x]];
return fa[x];
}
void uni(int x,int y)
{
x=find(x);
y=find(y);
fa[x]=y;
cnt[y]+=cnt[x];
cnt[x]=cnt[y];
if(p[mx[x]]>p[mx[y]])
{
mx[y]=mx[x];
}
else if(p[mx[x]]==p[mx[y]])
{
mx[y]=mx[x]<mx[y]?mx[x]:mx[y];
}
mx[x]=mx[y];
} int main()
{
freopen("test.in","r",stdin);
while(~scanf("%d",&n))
{
if(m>=) printf("\n");
for(int i=;i<n;i++) mx[i]=fa[i]=i,cnt[i]=;
for(int i=;i<n;i++) scanf("%d",p+i);
scanf("%d",&m);
for(int i=,a,b;i<=m;i++)
{
scanf("%d%d",&a,&b);
e.insert({a,b});//查询时e.find({a,b})!=e.end()||e.find({b,a})!=e.end()
}
scanf("%d",&q);
for(int i=;i<=q;i++)
{
int a,b=;
char str[];
scanf("%s%d",str,&a);
if(str[]=='d')
{
scanf("%d",&b);
it=e.find({a,b});
if(it==e.end()) it=e.find({b,a});
e.erase(it);
}
opt[i]={str[],a,b,i};
}
std::sort(opt+,opt++q);
for(it=e.begin();it!=e.end();it++)
uni(it->s,it->t);
int num=;
for(int i=;i<=q;i++)
{
if(opt[i].o=='d')
{
uni(opt[i].a,opt[i].b);
}
else//q
{
find(opt[i].a);
if(p[mx[opt[i].a]]<=p[opt[i].a]) ans[num++]=-;
else ans[num++]=mx[opt[i].a];
}
} while(num>) printf("%d\n",ans[--num]); e.clear();
}
return ;
}
Connections in Galaxy War
洛谷 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 根本没有思路的题,看了网 ...
- ZOJ 3261 Connections in Galaxy War(逆向并查集)
参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...
- 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为切断 ...
- 题解报告:zoj 3261 Connections in Galaxy War(离线并查集)
Description In order to strengthen the defense ability, many stars in galaxy allied together and bui ...
- zoj 3261 Connections in Galaxy War(并查集逆向加边)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...
- BZOJ 1015: [JSOI2008]星球大战starwar 并查集
1015: [JSOI2008]星球大战starwar Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝 ...
- BZOJ 1015 [JSOI2008]星球大战starwar
1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 3551 Solved: 1581[Submit ...
随机推荐
- luogu2746 校园网
题目大意: 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”).注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中. 你要 ...
- bzoj 1026 [ SCOI2009 ] windy数 —— 数位DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1026 蛮简单的数位DP,预处理 f[i][j] 表示 i 位数,以 j 开头的 windy ...
- bzoj3110 [Zjoi2013]K大数查询——线段树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110 外层权值线段树套内层区间线段树: 之所以外层权值内层区间,是因为区间线段树需要标记下传 ...
- Bootstrap 只读输入框
只读输入框 为输入框设置 readonly 属性可以禁止用户输入,并且输入框的样式也是禁用状态. <input class="form-control" type=&qu ...
- Python的学习(二十一)----Python的静态变量
前段时间在论坛里面有人提问说, class foo(): member1 member2 ... self.member1 foo.member2 其中的两个成员member1, member2有什么 ...
- Coursera Algorithms week2 栈和队列 练习测验: Stack with max
题目原文: Stack with max. Create a data structure that efficiently supports the stack operations (push a ...
- 2C课程笔记分享_StudyJams_2017
课程2C-实践:创建交互式应用 概述 课程2C的内容主要是练习巩固2A.2B中讲解的内容,并设计实现一款篮球比赛的计分板应用及其界面的美化. Warm-Up:准备活动 新建项目PracticeSet2 ...
- 算法之dfs篇
dfs算法是深度搜索算法.从某一节点开始遍历直至到路径底部,如果不是所寻找的,则回溯到上个节点后,再遍历其他路径.不断重复这个过程.一般此过程消耗很大,需要一些优化才能保持算法的高效. hdu1010 ...
- SQL Server2008优化之SET STATISTICS开关
一.准备工作 缓存对于某个查询的性能影响十分之大,所以优化之前要清空缓存. 清除Buffer Pool时面的所有缓存 DBCC DROPCLEANBUFFERS清除Buffer Pool里的所有缓存的 ...
- 【SQL】CASE与DECODE
1. case..when case..when语句用于按照条件返回查询结果,如当我们想把emp表的工资按照多少分成几个不同的级别,并分别统计各个级别的员工数.SQL语句如下: select (cas ...