HDU2860Regroup(并查集)

Regroup

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 660    Accepted Submission(s): 161

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.

看代码就明白题意。

#include<stdio.h>
const int N = 100005;
int fath[N],val[N],n;

void init()
{
    for(int i=0;i<=n;i++)
        fath[i]=i,val[i]=-1;
}
int findfath(int x)
{
    if(x!=fath[x])
        fath[x]=findfath(fath[x]);
    return fath[x];
}
int main()
{
    int k,m,a,b;
    char st[20];
    while(scanf("%d%d%d",&n,&k,&m)>0)
    {
        init();
        while(k--)
        {
            scanf("%d%d",&a,&b);
            if(val[b]==-1||val[b]>a)
                val[b]=a;
        }
        while(m--)
        {
            scanf("%s",st);
            if(st[0]=='A')
            {
                scanf("%d%d",&a,&b);
                if(fath[b]==b)
                {
                    if(val[b]==-1||val[b]>a)
                    val[b]=a;
                    printf("Accept\n");
                }
                else printf("Reject\n");
            }
            else if(st[0]=='M')
            {
                scanf("%d%d",&a,&b);
                if(fath[a]!=a||fath[b]!=b||a==b)
                {
                    printf("Reject\n"); continue;
                }
                printf("Accept\n");
                if(val[a]==-1||val[b]!=-1&&val[a]>val[b])
                    val[a]=val[b];
                fath[b]=a;
            }
            else
            {
                scanf("%d",&a);
                if(fath[a]!=a)
                {
                    b=findfath(a);
                    printf("Company %d is a part of company %d.\n",a,b);
                }
                else
                {
                    if(val[a]==-1)
                        printf("Company %d is empty.\n",a);
                    else printf("Lowest rate: %d.\n",val[a]);
                }
            }
        }
        printf("\n");
    }
}

时间: 2024-08-10 20:53:17

HDU2860Regroup(并查集)的相关文章

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

CodeForces 745C Hongcow Builds A Nation 并查集

题意: 给了你n个城市 m条边 k个政府 每个政府管辖的区域内不能和其他政府的区域有相连 即政府之间不存在路径 问你在维护这种关系的同时 最多再加多少条边 思路: 先找出来每个联通块 再找出来没有归属的孤立的点 把他们都放到最大的联通块里 然后每个联通块之间的点两两连边是n*(n-1)/2条边 最后算出来的ans-m就好了 (看别人的博客学了一个max_element 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a

并查集(个人模版)

并查集: 1 int find(int a) 2 { 3 int r=a; 4 while(f[r]!=r) 5 r=f[r]; 6 int i=a; 7 int j; 8 while(i!=r) 9 { 10 j=f[i]; 11 f[i]=r; 12 i=j; 13 } 14 return r; 15 } 16 int merge(int a,int b) 17 { 18 int A,B; 19 A=find(a); 20 B=find(b); 21 if(A!=B) 22 { 23 f[B

并查集应用

题目描述: One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls

【bzoj3674】 可持久化并查集加强版

http://www.lydsy.com/JudgeOnline/problem.php?id=3674 (题目链接) 题意 维护并查集3个操作:合并:回到完成第k个操作后的状态:查询. Solution 其实就是用主席树的叶子节点维护并查集的可持久化数组fa[]. 细节 终于认识到了按秩合并的强大,单纯写个路径压缩Re飞,写了路径压缩+按秩合并比单纯的按秩合并每快多少→_→ 代码 // bzoj3674 #include<algorithm> #include<iostream>

BZOJ1015[JSOI2008]星球大战starwar[并查集]

1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 5253  Solved: 2395[Submit][Status][Discuss] Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道互相直接或间接地连接. 但好景不长,很快帝国又重

HDU 5606 tree 并查集

tree 把每条边权是1的边断开,发现每个点离他最近的点个数就是他所在的连通块大小. 开一个并查集,每次读到边权是0的边就合并.最后Ans?i??=size[findset(i)],size表示每个并查集根的size Ans_i=size[findset(i)],sizeAns?i??=size[findset(i)],size表示每个并查集根的sizesize. #include<cstdio> #include<cstring> #include<algorithm>

HDU 5441 离线处理 + 并查集

题意:给n个节点m条带权值边的无向图.然后q个问题,每次询问点对的数目,点对需要满足的条件是:1)连通:2)其路径的最大权值不能超过询问值. 分析:如果没次询问一次,dfs一次,很可能超时,因此可以用并查集.离线处理,把边按权值排序,把问题按大小排序.然后离线的过程就是不断向图中加边的过程. 比如样例如下: 然后离线处理,排完序后将会是一条一条的加边:问题也排了序,因此是个累加过程... 1 #include <cstdio> 2 #include <iostream> 3 #in

poj1988 Cube Stacking(并查集

题目地址:http://poj.org/problem?id=1988 题意:共n个数,p个操作.输入p.有两个操作M和C.M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[1 6]上为[2 4 1 6]),C x为输出x下面有几个数. 思路:并查集每个集合以栈最下面的数为根,维护两个数组num[x]表示x所在集合节点总数,count[x]表示x下方节点个数.每次查找压缩路径的时候更新count(换父节点的时候每轮都把父节点的count加给儿子,就可以一直更新到x所在栈

习题:过路费(kruskal+并查集+LCA)

过路费  [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费为所经过城市之间道路长度的最大值.如:A 到 B 长度为 2,B 到 C 长度为 3,那么开车从 A 经过 B 到 C 需要上交的过路费为 3. 佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此 他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低 的行驶路线.然