[Swust OJ 1091]--土豪我们做朋友吧(并查集,最值维护)

 

题目链接:http://acm.swust.edu.cn/problem/1091/

 

Time limit(ms): 1000      Memory limit(kb): 32768
 

人都有缺钱的时候,缺钱的时候要是有个朋友肯帮助你,那将是一件非常幸福的事情。有N个人(编号为1到N),一开始他们互相都不认识,后来发生了M件事情,事情分为2个种类,1:A和B成为了朋友,并且A的所有朋友都成了B的朋友,B的所有朋友也都成了A的朋友。2:A缺钱了,请求帮助,他需要向他朋友中钱最多的请求帮助,若不止一位,选择编号最小的。

Description

多组测试数据,每组第一行是整数N(2<=N<=100000),表示有N个人,第二行N个数据,依次表示每个人有多少钱,第三行是M(1<=M<=100000),表示发生了M个事件。接下来是M行,首先输入事件种类P(1或者2),然后是对应的两个或者一个整数A,B或者A。数据保证都在32位以内。

Input

对于每一个事件2,输出A需要请求的人的编号,若没有人能够帮助他,输出"NO ONE CAN HELP!"。

Output
1
2
3
4
5
6
7
3
1 2 3
3
2 1
1 1 3
2 1
 
Sample Input
1
2
3
NO ONE CAN HELP!
3
 
Sample Output
输出换行请使用\r\n
 
解题思路:直接的一个并查集能过所有的数据,但是数据量过大,单纯的并查集会直接超时;
     那么在使用并查集将最大与次大元素找出,然后维护就可以了
(之所以找最大和次大,在并查集合并过程中初始化最大元素为自己,恩,你懂得~~)
代码如下:
 1 #include<iostream>

 2 #include<cstdlib>

 3 #include<cstring>

 4 using namespace std;

 5 int n, m, a, b, c, f[100001], val[100001];

 6 struct tuhao{

 7     int pos, money;

 8 };

 9 struct node{

10     tuhao max[4];

11 }x[100001];

12 int cmp(const void *x, const void *y){

13     if ((*(tuhao *)x).money == (*(tuhao *)y).money)

14         return (*(tuhao *)x).pos - (*(tuhao *)y).pos;

15     return (*(tuhao *)y).money - (*(tuhao *)x).money;

16 }

17 void init(){

18     memset(x, 0, sizeof(x));

19     for (int i = 1; i <= n; i++){

20         x[i].max[0].money = val[i];

21         x[i].max[0].pos = f[i] = i;

22  

23     }

24 }

25 int findset(int k){

26     int i = k, j = k, r;

27     while (i != f[i])

28         i = f[i];

29     while (j != i){

30         r = f[j];

31         f[j] = i;

32         j = r;

33     }

34     return i;

35 }

36 void mergy(int a, int b){

37     int tx = findset(a), ty = findset(b), i;

38     if (tx != ty){

39         f[ty] = tx;

40         for (i = 2; i < 4; i++){

41             x[tx].max[i].pos = x[ty].max[i - 2].pos;

42             x[tx].max[i].money = x[ty].max[i - 2].money;

43         }

44         qsort(x[tx].max, 4, sizeof(x[tx].max[0]), cmp);

45         for (i = 2; i < 4; i++)

46             x[tx].max[i].pos = x[tx].max[i].money = 0;

47     }

48 }

49 void Search(int k){

50     int v = findset(k);

51     if (!x[v].max[1].pos)

52         cout << "NO ONE CAN HELP!\r\n";

53     else

54         cout << (x[v].max[0].pos == k ? x[v].max[1].pos : x[v].max[0].pos) << "\r\n";

55 }

56 int main(){

57     while (cin >> n){

58         for (int i = 1; i <= n; i++)

59             cin >> val[i];

60         init();

61         cin >> m;

62         for (int i = 0; i < m; i++){

63             cin >> a;

64             switch (a){

65             case 1:cin >> b >> c; mergy(b, c); break;

66             default:cin >> b; Search(b); break;

67             }

68         }

69     }

70     return 0;

71 }
View Code

 

你可能感兴趣的:(并查集)