zoj 3261 Connections in Galaxy War:逆向并查集

链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261

题目:

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

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

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

题目大意:

银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可通过通道找到能量值最大的星球来帮忙。但是有一些通道被怪兽破坏了。

现在先给出原来的所有通道, 然后进行询问,询问有两种方式:

destroy a b: 连接a,b的通道被怪兽破坏了

query a: 询问a能否通过通道找到救兵。

分析与总结:

如果直接按照惯性思维,先用并查集把所有通道连起来,然后在删除边,那么恐怕没什么可行性。

一个很巧妙的方法是,我们可以按照逆向思维,先离线输入所有的输入,然后把被破坏之后的通道连接起来,然后在从最后一个询问往前面推,当有destroy a b时就把a,b再Union起来。

代码:

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;  

const int HASH = 10000;
const int N = 10005;
const int M = 20005;  

map<int, bool>mp;  

int f[N];
int rank[N];
int n,m,Q;
int ans[50005];  // 保存答案  

struct Buit{
    int u, v;
}built[M];  

struct Query{
    char cmd[10];
    int a, b;
}query[50005];  

void make_set(){
    for(int i=0; i<n; ++i) f[i]=i;
}
int find(int x){
    int i,j=x;
    while(j!=f[j]) j=f[j];
    while(x!=j){i=f[x]; f[x]=j; x=i;}
    return j;
}
void Union(int x,int y){
    int a=find(x),b=find(y);;
    if(a==b)return ;
    if(rank[a]>rank[b]) f[b]=a;
    else if(rank[a]<rank[b]) f[a]=b;
    else{
        if(a>b) f[a]=b;
        else f[b]=a;
    }
}  

int main(){
    bool flag=false;
    while(~scanf("%d",&n)){
        for(int i=0; i<n; ++i)
            scanf("%d",&rank[i]);
        scanf("%d",&m);
        for(int i=0; i<m; ++i){
            scanf("%d%d",&built[i].u, &built[i].v);
            if(built[i].u>built[i].v){
                swap(built[i].u, built[i].v);
            }
        }
        scanf("%d",&Q);
        mp.clear();
        for(int i=0; i<Q; ++i){
            scanf("%s",query[i].cmd);
            if(query[i].cmd[0]=='q') scanf("%d",&query[i].a);
            else{
                scanf("%d%d",&query[i].a,&query[i].b);
                if(query[i].a>query[i].b) swap(query[i].a,query[i].b);
                mp[query[i].a*HASH+query[i].b]=true;;
            }
        }
        // 合并没有删除的边
        make_set();
        for(int i=0; i<m; ++i)if(!mp[built[i].u*HASH+built[i].v]){
            Union(built[i].u, built[i].v);
        }
        // 询问
        int k=0;
        for(int i=Q-1; i>=0; --i){
            if(query[i].cmd[0]=='q'){
                int fa=find(query[i].a);
                if(rank[fa]>rank[query[i].a]) ans[k++]=fa;
                else ans[k++]=-1;
            }
            else{
                Union(query[i].a,query[i].b);
            }
        }
        if(flag)puts("");
        else flag=true;
        for(int i=k-1; i>=0; --i)
            printf("%d\n", ans[i]);
    }
    return 0;
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索war
, help
, power
, to
, The
, connections
which
kiss in the galaxy、rarecuinthegalaxy、kiss in galaxy结局、galaxy in kiss、galaxy on7 00in mode,以便于您获取更多的相关知识。

时间: 2024-08-31 05:48:05

zoj 3261 Connections in Galaxy War:逆向并查集的相关文章

zoj 3261 Connections in Galaxy War

点击打开链接zoj 3261 思路: 带权并查集 分析: 1 题目说的是有n个星球0~n-1,每个星球都有一个战斗值.n个星球之间有一些联系,并且n个星球之间会有互相伤害 2 根本没有思路的题,看了网上的思路才知道是逆向并查集.如果我们按照正常的并查集来做,以战斗值最大为根节点的话,当询问的时候很容易,但是碰到删除边的时候就很困难了,所以这里才用逆向的并查集思路 3 我们先把所有的输入保存,然后我们可以这么考虑,从后面往前面枚举q次条件,如果是destroy我们认为是加边,这样的话就很好维护并查

算法:ZOJ 3659 Conquer a New Region(并查集)

[题目大意] 有N个城市,N-1条路把这些城市连起来(刚好是一个树).相邻的两个城市有一个 运输容量C(i, j),而城市x到城市y的那条路的运输能力S取决与这条路上所经过的所有路中最小的那个容量 . 以那一个城市为中心,到其他N-1个城市的运输能力总和最大? [思路] 用神奇的并查集 ,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路,这条路连 接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值 大

并查集专题【完结】

个人整理 并查集 [poj] 第一题 poj 1182 食物链 点击打开链接poj 1182 思路: 带权并查集 分析: 1 典型的带权并查集的题目 2 如果x和y是同类的关系认为是0,如果是x吃y那么关系认为是1,那么x和y的关系为2就说明y吃x 3 那么如果x和y同类则rank[x] == rank[y] , 如果x吃y那么rank[x] == (rank[y]+1)%3 , 注意mod3的使用 点击查看代码 第二题 poj 1308 Is It A Tree? 点击打开链接 poj 130

POJ题目分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

poj 3164 Command Network:最小树形图模板题

链接: http://poj.org/problem?id=3164 题目: Command Network Time Limit: 1000MS     Memory Limit: 131072K Total Submissions: 8922     Accepted: 2609 Description After a long lasting war on words, a war on arms finally breaks out between littleken's and Knu

《程序设计解题策略》——1.2 利用最小生成树及其扩展形式解题

1.2 利用最小生成树及其扩展形式解题 设G=(V,E,ω)是连通的有权无向图(节点集为V,边集为E,边权集为ω),连通图G中包含所有节点,且只有V-1条边的连通子图即为G的生成树.边权值和最小的生成树称为最小生成树.在现实生活中,最小生成树的原理和算法有着广泛的应用.程序设计竞赛中与最小生成树有关的试题一般有两类: 1) 构建最小生成树. 2) 应用最小生成树原理优化算法. 本节除了深入研讨最小生成树的性质和求解方法外,还给出了三种特殊类型生成树: 1) 最优比率生成树. 2) 最小k度限制生

ACM练级

一般要做到50行以内的程序不用调试.100行以内的二分钟内调试成功.acm主要是考算法的 ,主要时间是花在思考算法上,不是花在写程序与debug上.  下面给个计划你练练: 第一阶段: 练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打 出来.  1.最短路(Floyd.Dijstra,BellmanFord)  2.最小生成树(先写个prim,kruscal要用并查集,不好写)  3.大数(

使用WEBLOGIC PORTAL规则引擎中实现动态业务逻辑

web|动态 简介 业务应用的需求总是随着业务环境的变化趋势而不断地改变.决策很少是一成不变的,并且竞争压力要求业务逻辑的设计和实现具有灵活性,以快速地适应不断变化的需求.通常,对业务逻辑的更改必须由开发人员来完成,然后进行多次彻底的测试,而这将是一个很耗时的过程.在应用程序的修改工作完成后,需要将其重新部署到服务器,需要留出预定的停机时间,以防应用程序对用户不可用. 对于这个问题,更好的解决方案是通过应用程序之外的一组规则来实现某些业务决策.这些规则并没有被编译到应用程序中,而是在运行时读取并

HDU 3926:Hand in Hand(同构图)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3926 原题: Hand in Hand Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 122768/62768 K (Java/Others) Total Submission(s): 731    Accepted Submission(s): 294 Problem Description In order to get rid o