您的位置:首页 > 其它

hdu 2860 Regroup 带权并查集

2016-07-07 20:05 387 查看
题意:给出n,k,m,有n个军队,k个士兵,m个操作。

输入:n,k,m 

   然后k行,每行两个数x y 

  代表HQ为x的士兵加入军团y

之后m行,有三种形式:

AP x y
A recruit with ability rate x were asked to join company y. (0<=x<2^31, 0<=y<n)

HQ为x 的士兵加入军团y

输出"Accept"

或"Reject" 如果y已经归并到其它军团

  MG x y
Company x and company y is merged. The new company is numbered as x. (0<=x, y<n)

将军团y归并到军团x

输出"Accept"

或"Reject" 如果y或x已经归并到其它军团

坑点是如果x==y,那么输出"Reject"

  GT x
Report the fighting capacity of company x. (0<=x<n)
报告军团x中士兵HQ最低值,

如果军团x已经归并到其他军团那么输出"Company x is a part of company z."

如果没有士兵,输出 "Company x is empty."

否则 “Lowest rate: y.”

        

解法:

带权并查集,和一般的并查集唯一的区别就是多了一个数组记录每个点的权值。

以每个军团为结点并查集,并且都有一个权值代表该军团士兵的最低HQ。

只需要在新兵进入军团或者军团归并时特殊处理一下就可以了。


Regroup

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

Total Submission(s): 931    Accepted Submission(s): 235


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.

 

Source

2009 Multi-University Training
Contest 5 - Host by NUDT

 

Recommend

gaojie   |   We have carefully selected several similar problems for you:  2858 2861 2855 2856 2857 

 

Statistic | Submit | Discuss | Note

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn= 100000   ;
//const int maxV=12    ;
int n,k,m;
int a[maxn+4],pre[maxn+4];
char op[5];

void init()
{
for(int i=0;i<n;i++)
{
a[i]=-1,pre[i]=i;
}
}
int find(int x)
{
return pre[x]==x?x:pre[x]=find(pre[x]);
}

void addto(int x,int which)
{
if(a[which]==-1)   {a[which]=x;return;}
a[which]=min(a[which],x);
}

void add()
{
int x,y;
scanf("%d%d",&x,&y);
int rooty=find(y);
if(rooty!=y)
{
puts("Reject");
return;
}

addto(x,rooty);
puts("Accept");
}

void MG()
{

int x,y;
scanf("%d%d",&x,&y);
int rootx=find(x);
int rooty=find(y);
//    if(rootx!=x||rooty!=y)
if(rootx!=x||rooty!=y||x==y)
{
puts("Reject");
return;
}
pre[rooty]=rootx;

if(a[rooty]==-1||a[rootx]==-1)  a[rootx]=max(a[rootx],a[rooty]);
else  a[rootx]=min(a[rootx],a[rooty]);
puts("Accept");
}

void query()
{
int x;
scanf("%d",&x);
int root=find(x);
if(root!=x)
{
printf("Company %d is a part of company %d.\n",x,root);
return;
}
if(a[x]==-1)
{
printf("Company %d is empty.\n",x);
return;
}
printf("Lowest rate: %d.\n",a[x]);
}
void work()
{
for(int i=1;i<=m;i++)
{
scanf("%s",op);
if(strcmp(op,"GT")==0)  query();
else if(strcmp(op,"AP")==0) add();
else if(strcmp(op,"MG")==0)  MG();
}
putchar('\n');
}
int main()
{
while(~scanf("%d%d%d",&n,&k,&m))
{
init();
int x,y;
for(int i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
addto(x,y);
}
work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: