ZOJ3261 Connections in Galaxy War —— 反向并查集
题目链接:https://vjudge.net/problem/ZOJ-3261
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
题解:
1.可以想到用并查集处理。题目还要求毁掉一些边,那么并查集也需要解除一些点的关系。但并查集只能建立关系,不能解除关系(至少是很难实现的)。
2.既然并查集的强项是建立关系,那么我们就不要强人所难,硬要人家实现解除关系的功能,而要充分利用其强项,怎么利用?先把最终状态建立出来。然后再将操作顺序逆过来:从最后一步操作开始执行,直到第一步结束。当遇到毁边的操作(即解除关系),由于我们是逆向操作,所以此时应该建边(即建立联系)。
vector循环:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e5+; int n, m, k;
int a[MAXN], fa[MAXN], ans[MAXN];
vector<int> g[MAXN]; struct node
{
int op, u, v;
}q[MAXN]; int find(int x){ return fa[x]==x?x:x=find(fa[x]); } void Union(int u, int v)
{
u = find(u);
v = find(v);
if(u>v) swap(u, v); //把u设置为编号小得到
if(u!=v)
{
if(a[u]>=a[v]) fa[v] = u; //如果值相等, 则要编号小的
else fa[u] = v; //a[fu]<a[fv]
}
} int main()
{
int kase = ;
while(scanf("%d", &n)!=EOF)
{
if(kase++) printf("\n");
for(int i = ; i<n; i++)
{
scanf("%d", &a[i]);
g[i].clear();
fa[i] = i;
} scanf("%d", &m);
for(int i = ; i<=m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
if(u>v) swap(u, v);
g[u].push_back(v);
} scanf("%d", &k);
for(int i = ; i<=k; i++)
{
char s[];
int u, v;
scanf("%s", s);
if(!strcmp(s, "destroy"))
{
q[i].op = ;
scanf("%d%d", &u, &v);
if(u>v) swap(u, v);
q[i].u = u; q[i].v = v; //记录查询
for(int j = ; j<g[u].size(); j++) //标记为-1, 表示删除
if(g[u][j]==v){ g[u][j] = -; break; }
}
else
{
q[i].op = ; //记录查询
scanf("%d", &q[i].u);
}
} for(int i = ; i<n; i++)
for(int j = ; j<g[i].size(); j++)
if(g[i][j]!=-) //如果是有效结点, 则合并
Union(i, g[i][j]); for(int i = k; i>=; i--) //从后往前
{
if(q[i].op==) Union(q[i].u, q[i].v);
else
{
int f = find(q[i].u);
ans[i] = (a[f]>a[q[i].u]?f:-);
}
} for(int i = ; i<=k; i++)
if(q[i].op==)
printf("%d\n", ans[i]);
}
}
map优化:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e5+; int n, m, k;
int a[MAXN], fa[MAXN], ans[MAXN]; struct node
{
int op, u, v;
};
node q[MAXN], edge[MAXN];
map<int, int>M[MAXN];
int destroyed[MAXN]; int find(int x){ return fa[x]==x?x:x=find(fa[x]); } void Union(int u, int v)
{
u = find(u);
v = find(v);
if(u>v) swap(u, v); //把u设置为编号小得到
if(u!=v)
{
if(a[u]>=a[v]) fa[v] = u; //如果值相等, 则要编号小的
else fa[u] = v; //a[fu]<a[fv]
}
} int main()
{
int kase = ;
while(scanf("%d", &n)!=EOF)
{
if(kase++) printf("\n");
for(int i = ; i<n; i++)
{
scanf("%d", &a[i]);
fa[i] = i;
M[i].clear();
} memset(destroyed, , sizeof(destroyed));
scanf("%d", &m);
for(int i = ; i<=m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
if(u>v) swap(u, v);
edge[i].u = u;
edge[i].v = v;
M[u][v] = i; //记录边的编号
} scanf("%d", &k);
for(int i = ; i<=k; i++)
{
char s[];
int u, v;
scanf("%s", s);
if(!strcmp(s, "destroy"))
{
q[i].op = ;
scanf("%d%d", &u, &v);
if(u>v) swap(u, v);
q[i].u = u; q[i].v = v;
destroyed[M[u][v]] = ; //M[u][v]为边的编号,表明这条边被毁坏
}
else
{
q[i].op = ;
scanf("%d", &q[i].u);
}
} for(int i = ; i<=m; i++)
if(!destroyed[i]) //如果这条边没有被毁坏,则合并两端点
Union(edge[i].u, edge[i].v); for(int i = k; i>=; i--)
{
if(q[i].op==) Union(q[i].u, q[i].v);
else
{
int f = find(q[i].u);
ans[i] = (a[f]>a[q[i].u]?f:-);
}
} for(int i = ; i<=k; i++)
if(q[i].op==)
printf("%d\n", ans[i]);
}
}
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 ,并查集删边
In order to strengthen the defense ability, many stars in galaxy allied together and built many bidi ...
- 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(并查集逆向加边)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...
- ZOJ - 3261 Connections in Galaxy War(并查集删边)
https://cn.vjudge.net/problem/ZOJ-3261 题意 银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可 ...
- ZOJ-3261 Connections in Galaxy War 并查集 离线操作
题目链接:https://cn.vjudge.net/problem/ZOJ-3261 题意 有n个星星,之间有m条边 现一边询问与x星连通的最大星的编号,一边拆开一些边 思路 一开始是真不会,甚至想 ...
- ZOJ3261 Connections in Galaxy War 并查集
分析:对于这种删边操作,我们通常可以先读进来,然后转化离线进行倒着加边 #include <stdio.h> #include <string.h> #include < ...
随机推荐
- luogu3157 [CQOI2011]动态逆序对
先算出一个点前头比它大和后头比它小的数量. 每次删点就扔进一个主席树里头,防止造成重复删答案. #include <iostream> #include <cstring> # ...
- CD(01背包)
You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is o ...
- PTA 05-树8 File Transfer (25分)
题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/670 5-8 File Transfer (25分) We have a netwo ...
- [HDU2896]病毒侵袭(AC自动机)
传送门 题目中文描述,赞! 除了val记录id以外就是模板. 注意:每次数组都要清0.0 ——代码 #include <cstdio> #include <queue> #in ...
- POJ 1273 Drainage Ditches【图论,网络流】
就是普通的网络流问题,想试试新学的dinic算法,这个算法暑假就开始看国家集训队论文了,之前一直都只用没效率的EK算法,真正学会这个算法还是开学后白书上的描述:dinic算法就是不断用BFS构建层次图 ...
- bzoj 3223 文艺平衡树 splay 区间翻转
Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17715 Solved: 7769[Submit][Status][ ...
- SpringBoot配置Bean的两种方式--注解以及配置文件
一.注解方式 编写实体类: package com.example.bean; import org.springframework.boot.context.properties.Configura ...
- js面试题总结
1.typeof和Object.prototype.toString typeof是js里面判断变量类型的一种方法,但这种方法没有Object.prototype.toString准确,前者有6种判断 ...
- c++之函数对象、bind函数
函数对象实质上是一个实现了operator()--括号操作符--的类. class Add { public: int operator()(int a, int b) { return a + b; ...
- 学习LaTex
MarkDown+Latex 本来想学习latex编辑公式的,在博客园内置的MarkDown编辑器已经支持Latex公式解析了,如下: $$x=\frac{-b\pm\sqrt{b^2-4ac}}{2 ...