Hdu2860-Regroup(种类并查集)

Problem Description

When ALPC42 got to a panzer brigade, He was asked to build software to help them regroup the battalions or companies. As the tradition of army, soldiers are rated according his or her abilities, taking the rate as an integer. The fighting capacity of a company is determined by the soldier in this company whose rate is lowest. Now the recruits those rated are coming and join to their companies according to the order form HQ. With the coming of new recruits, a big regroup action reached, asking to merge some companies into one. The designation of a company, however, will not be canceled, but remain for memorialize what the company is done, means the designation of the company is still exist, but the company is gone, so it is unable to ask recruits to join this company, or merge the company into others. A strange thing is, the orders sometimes get wrong, send newbie to a company which is already merged into another, or mentioned some only-designation-existed companies. Such order could be rejected. The brigadier wants to know every change of each order, so the program should able to report the status of every order, telling whether it is accept, and can query the fighting capacity of specified company. (To simplify, companies are numbered from 0 to n-1

Input

There may be several test cases. For each case, the integers in first line, n, k, m, telling that there are n companies, k soldiers already, and m orders needs be executed. (1<=n ,k ,m<=100000). Then k lines with two integers R and C for each, telling a soldier with rate R is now in company C Then m lines followed, containing 3 kinds of orders, in upper case:   AP x y A recruit with ability rate x were asked to join company y. (0<=x<2^31, 0<=y<n)
  MG x y Company x and company y is merged. The new company is numbered as x. (0<=x, y<n)
  GT x Report the fighting capacity of company x. (0<=x<n)

Output

For each order there is exact one line to report the result. For AP and MG order, print “Accept” if it is able to be done, and execute it, or “Reject” if it is an illegal order. For GT order, if company x is still exist (not merged into others), print as “Lowest rate: y.” which y is the minimal rate of soldiers in this company. If there is no one in this company, tell "Company x is empty." If company x is already merged into others, print "Company x is a part of company z." z is the company where the company x is in. Print a blank line after each case

Sample Input

5 5 10

5 0

5 1

5 2

5 1

5 0

GT 0

GT 3

AP 3 3

GT 3

GT 4

MG 3 4

GT 4

MG 1 3

GT 4

GT 1

Sample Output

Lowest rate: 5.

Company 3 is empty.

Accept

Lowest rate: 3.

Company 4 is empty.

Accept

Company 4 is a part of company 3.

Accept

Company 4 is a part of company 1.

Lowest rate: 3.

题意:有n个公司,有k个人,会给出k个人的能力值和处于哪个公司。然后有m个操作,分别有3种不同的操作

AP x y 能力值为x的人加入到y公司中

MG x y x公司和y公司合并

GT x 查询x公司中能力值最小值

如果某个公司已经被别的公司合并了,则其他人不能加入此公司,此公司也不能再跟其他公司合并,对于AP和MG操作,如果可行则输出Accept,并执行此

操作,不能则输出Reject,忽略此操作。对于GT操作,如果此公司未被合并,则输出此公司中能力值最小值Lowest rate: 能力值. ,此公司没人则输出

Company 编号 is empty.否则输出Company 此公司编号 is a part of company 合并的公司编号.

解析:很明显的种类并查集,在合并的过程中更新一下能力值。这道题有一个坑点,如果x==y则直接输出Reject。。。。。。。。

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
typedef __int64 LL;
const LL INF=1e12+7;
const int maxn=100005;
LL Min(LL a,LL b){ return a<b?a:b; }
int N,K,M;
LL val[maxn];
int d[maxn];
int root(int a)
{
    if(d[a]==a) return a;
    int t=d[a];
    d[a]=root(d[a]);
    //val[a]=Min(val[a],val[t]);
    return d[a];
}
void FunA()
{
    LL x;
    int y;
    scanf("%lld%d",&x,&y);
    int ra=root(y);
    if(ra!=y) printf("Reject\n");
    else
    {
        printf("Accept\n");
        val[ra]=Min(val[ra],x);
    }
}
void FunM()
{
    int x,y;
    scanf("%d%d",&x,&y);
    if(x==y){ printf("Reject\n"); return; }
    int ra=root(x);
    int rb=root(y);
    if(ra!=x||rb!=y) printf("Reject\n");
    else
    {
        d[rb]=ra;
        val[ra]=Min(val[ra],val[rb]);
        printf("Accept\n");
    }
}
void FunG()
{
    int x;
    scanf("%d",&x);
    int ra=root(x);
    if(ra!=x) printf("Company %d is a part of company %d.\n",x,ra);
    else if(val[ra]==INF) printf("Company %d is empty.\n",ra);
    else printf("Lowest rate: %lld.\n",val[ra]);
}
int main()
{
    while(scanf("%d%d%d",&N,&K,&M)!=EOF)
    {
        LL r;
        int c;
        for(int i=0;i<maxn;i++) val[i]=INF,d[i]=i;
        for(int i=1;i<=K;i++)
        {
            scanf("%lld%d",&r,&c);
            val[c]=Min(val[c],r);
        }
        char op[5];
        while(M--)
        {
            scanf("%s",op);
            if(op[0]==‘A‘) FunA();
            else if(op[0]==‘M‘) FunM();
            else FunG();
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-08-10 20:53:21

Hdu2860-Regroup(种类并查集)的相关文章

poj 2492 a bug&#39;s life 简单种类并查集

题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. 1 #include<cstdio> 2 using namespace std; 3 const int MAXN=50010; 4 int fa[MAXN]; 5 int rel[MAXN]; // 0代表同类,1代表吃fa[i],2代表被吃 6 void _set(int n) 7 { 8 for(int i=1;i&l

POJ1182 食物链---(经典种类并查集)

题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 69207   Accepted: 20462 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食

poj1733(种类并查集+离散化)

题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第y个字符中间1的个数为偶数个, x, y, odd表示第x到第y个字符中间1的个数为奇数个, 若m句话中第k+1是第一次与前面的话矛盾, 输出k; 思路: 若x, y之间1的个数为偶数个, 那么1~x 与1~y中1的个数同奇偶性, 反之则异奇偶性, 我们可以将其理解为若输入x, y, even, 即

POJ1703--Find them, Catch them(种类并查集)

Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 32909Accepted: 10158 Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, t

poj 1182 食物链(种类并查集 ‘初心者’)

题目链接:http://poj.org/problem?id=1182 借着这题可以好好理解一下种类并查集,这题比较简单但挺经典的. 题意就不解释了,中问题. 关于种类并查集结局方法也是挺多的 1扩增倍数. 就是有几种关系就建立几倍数组,具体方法在这里不详细说了,这种方法有弊端 比较复杂而且内存消耗比较大如果关系比较多就容易爆掉. 2向量的方法. 这种方法要详细解说一下.这个方法好处都有啥.......(自行脑补后面的话) 这个方法的优点占用内存比较小而且比较简洁.只要找到关系就行. 下面就用方

poj1417(种类并查集+dp)

题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示x说y是天使,ch为no表示x说y不是天使(x, y为天使,恶魔的编号,1<=x,y<=p+q):天使只说真话,恶魔只说假话: 如果不能确定所有天使的编号,输出no,若能确定,输出所有天使的编号,并且以end结尾: 注意:可能会有连续两行一样的输入:还有,若x==y,x为天使: 思路:种类并查集+

种类并查集

//http://acm.timus.ru/problem.aspx?space=1&num=1003//分析:树和递归最常用的思想是分治:并查集是一种合并树的数据结构:合并树或加入树节点时,我们只在意新建立的树边上相邻的两个树节点之间的关系,实际上树边只在意相邻两个树节点之间的关系//思路:可以讲一段连续区间的奇偶性表示成两个前缀和的奇偶性:将出现的离散的点用map离散化一下:将数量减少的点做一次种类并查集 1 #include"iostream" 2 #include&qu

HDU 3038 How Many Answers Are Wrong(种类并查集)

题目链接 食物链类似的题,主要是在于转化,a-b的和为s,转换为b比a-1大s.然后并查集存 此节点到根的差. 假如x的根为a,y的根为b: b - y = rank[y] a - x = rank[x] y - x = s 可以推出b - a = rank[y] - rank[x] + s; 并查集 延迟更新什么的,都忘了啊. 还有这题,如果是x--的话,记得更新0的根. #include <cstring> #include <cstdio> #include <stri

hdoj-1289-A Bug&amp;#39;s Life【种类并查集】

A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11386 Accepted Submission(s): 3709 Problem Description Background Professor Hopper is researching the sexual behavior of a rare specie