zoukankan      html  css  js  c++  java
  • [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
    输出换行请使用
     
    解题思路:直接的一个并查集能过所有的数据,但是数据量过大,单纯的并查集会直接超时;
         那么在使用并查集将最大与次大元素找出,然后维护就可以了
    (之所以找最大和次大,在并查集合并过程中初始化最大元素为自己,恩,你懂得~~)
    代码如下:
     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!
    ";
    53     else
    54         cout << (x[v].max[0].pos == k ? x[v].max[1].pos : x[v].max[0].pos) << "
    ";
    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
  • 相关阅读:
    【python进阶】哈希算法(Hash)
    【数据库】MongoDB操作命令
    【数据库】MongoDB安装&配置
    【python基础】元组方法汇总
    【python基础】集合方法汇总
    滴水穿石-04Eclipse中常用的快捷键
    滴水穿石-03一道面试题引发的思考
    滴水穿石-02制作说明文档
    滴水穿石-01JAVA和C#的区别
    步步为营101-同一个PCode下重复的OrderNumber重新排序
  • 原文地址:https://www.cnblogs.com/zyxStar/p/4574735.html
Copyright © 2011-2022 走看看