zoukankan      html  css  js  c++  java
  • 并查集+优先队列+启发式合并 || 罗马游戏 || BZOJ 1455 || Luogu p2713

    题面:P2713 罗马游戏

    题解:

    超级大水题啊,特别水。。

    并查集维护每个人在哪个团里,优先队列维护每个团最低分和最低分是哪位,然后每次判断一下哪些人死了,随便写写就行

    并查集在Merge时可以用启发式合并,就是把小的团往大的团并,这样显然会更优。当然不写启发式合并应该也能过,就是慢一点。

    然后我们也可以写一个按秩合并让它更快233但是没有必要

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<queue>
     4 using namespace std;
     5 inline int rd(){
     6     int x=0;char c=getchar();
     7     while(c<'0'||c>'9')c=getchar();
     8     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     9     return x;
    10 }
    11 const int maxn=1000005,maxm=100005;
    12 int N,M,fa[maxn],A,B,f1,f2;
    13 bool Died[maxn];
    14 char o[2];
    15 struct Peo{
    16     int id,data;
    17     bool operator < (const Peo&a)const{
    18         return a.data<data;
    19     }
    20 }peo;
    21 priority_queue<Peo>pri[maxn];
    22 inline int getf(int n){
    23     if(fa[n]==n) return n;
    24     fa[n]=getf(fa[n]);
    25     return fa[n];
    26 }
    27 int main(){
    28     N=rd();
    29     for(int i=1;i<=N;i++){
    30         fa[i]=i;
    31         peo.id=i; peo.data=rd();
    32         pri[i].push(peo);
    33     }
    34     M=rd();
    35     while(M--){
    36         scanf("%s",o);
    37         if(o[0]=='M'){
    38             A=rd(); B=rd();
    39             f1=getf(A); f2=getf(B);
    40             if(Died[A] || Died[B] || f1==f2)                
    41                 continue;
    42             if(pri[f1].size()>pri[f2].size()) swap(f1,f2);
    43             while(!pri[f1].empty()){
    44                 if(!Died[(pri[f1].top()).id])
    45                     pri[f2].push(pri[f1].top());
    46                 pri[f1].pop();
    47             }
    48             fa[f1]=f2;
    49         }
    50         else{
    51             A=rd();
    52             if(Died[A]){
    53                 printf("0
    ");
    54                 continue;
    55             }
    56             f1=getf(A);            
    57             if(!pri[f1].empty()){
    58                 printf("%d
    ",(pri[f1].top()).data);
    59                 Died[(pri[f1].top()).id]=1;
    60                 pri[f1].pop();                
    61             }
    62             else printf("0
    ");
    63         }
    64     }
    65     return 0;
    66 }
    View Code

    By:AlenaNuna

  • 相关阅读:
    xml和json笔记
    Ajax开发技术介绍与实战练习
    MATLAB学习(4)——min
    MATLAB学习(2)——zeros
    MATLAB学习(1)——ordfilt2
    vim的基本命令
    VS2015 闪退问题
    Error (10028): Can't resolve multiple constant drivers for net "mydata[14]" at sd_read.v(207)
    自动识别设备
    Internal Error: Sub-system: CUT, File: /quartus/db/cut/cut_post_syn_util.cpp, Line: 709 name_to_atom_map[iname] == 0
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/11618863.html
Copyright © 2011-2022 走看看