并查集+优先队列+启发式合并 || 罗马游戏 || BZOJ 1455 || Luogu p2713

题面:P2713 罗马游戏

题解:

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

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

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

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

代码:

 1 #include
 2 #include
 3 #include
 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_queuepri[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\n");
54                 continue;
55             }
56             f1=getf(A);            
57             if(!pri[f1].empty()){
58                 printf("%d\n",(pri[f1].top()).data);
59                 Died[(pri[f1].top()).id]=1;
60                 pri[f1].pop();                
61             }
62             else printf("0\n");
63         }
64     }
65     return 0;
66 }
View Code

 


By:AlenaNuna

 

你可能感兴趣的:(并查集+优先队列+启发式合并 || 罗马游戏 || BZOJ 1455 || Luogu p2713)