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 < ...
随机推荐
- JSP默认选中下拉框的某一项
注意<c:if>标签要写在<option>标签里面 <select id="salesInventory_${s.index}" style=&quo ...
- 七、整合SQL基础和PL-SQL基础
--Oracle数据库重要知识点整理 2017-01-24 soulsjie 目录 --一.创建及维护表... 2 --1.1 创建... 2 --1.2 维护表... 2 --二.临时表的分类.创建 ...
- HDU 5245
题目大意: 每次随机选择两个点,便把这两个点之间形成的子矩阵上的每一个方块涂色,问随机选择k次,整个m*n的矩阵中有多少个小方块被涂上了颜色 这道题不难,但自己智商实在捉急,一直想不出来... 因为这 ...
- POJ 1300 最基础的欧拉回路问题
题目大意: 从0~n-1编号的房间,从一个起点开始最后到达0号房间,每经过一扇门就关上,问最后能否通过所有门且到达0号房间 我觉得这道题的输入输出格式是我第一次遇到,所以在sscanf上也看了很久 每 ...
- hdu 2669 扩展欧几里得(裸)
#include<stdio.h> #include<iostream> #define ll __int64 ll gcd(ll a,ll b,ll &x,ll &a ...
- HDU 4651 (生成函数)
HDU 4651 Partition Problem : n的整数划分方案数.(n <= 100008) Solution : 参考资料: 五角数 欧拉函数 五边形数定理 整数划分 一份详细的题 ...
- UVA 10200 Prime Time【暴力,精度】
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
- P1003 铺地毯(noip 2011)
洛谷——P1003 铺地毯 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯 ...
- 寒武纪camp网络测试赛
寒武纪camp网络测试赛 地址:oj点我进入 A(树形dp+树链剖分) 题意: 分析: 考虑树形dp,f0(x)和f1(x)分别表示以x为根的子树,不取x点或取x点的最大合法子集的元素个数 那么对于一 ...
- 从Java代码到字节码
http://www.importnew.com/13107.html http://blog.csdn.net/dc_726/article/details/7944154/ http://www. ...