ZOJ - 3261 (并查集倒序操作)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261

刚开始感觉要并查集删除节点这样的操作,但是开辟的空间会大。去找题解,都是并查集的离线操作。

于是就自己去用离线操作做一下。

虽然a了,但是感觉还是删除好啊!!

万一题目有要破坏两次咧!!

比如:

2
10 20
1
0 1
5
query 0
destroy 0 1
query 0
destroy 0 1
query 0
这样得出的答案,显然错误。但是这道题的题意就是破坏了就没有了,不能再破坏了。
对于这种情况,只需要在,seek处进行小操作。
但是这道题目不需要,qwq。
 1 #include<cstdio>
 2 #include<map>
 3 using namespace std;
 4 const int maxn=10006;
 5 int fa[maxn],val[maxn];
 6 struct node{
 7     int a,b,c;
 8 }fir[maxn*2],sec[maxn*5];
 9 int ans[maxn*5];
10 map<int,map<int,bool> > seek;
11 int find_fa(int x){ return fa[x]==x?x:fa[x]=find_fa(fa[x]); }
12 void add_edge(int a,int b)
13 {
14     int iop=find_fa(a);
15     int kop=find_fa(b);
16     if(iop!=kop){
17         if(val[iop]>val[kop]||(val[iop]==val[kop]&&iop<kop))
18             fa[kop]=iop;
19         else fa[iop]=kop;
20     }
21 }
22 int main()
23 {
24     int n,flag=0;
25     while( ~scanf("%d",&n)){
26         if(flag) puts("");
27         flag=1;
28         for(int i=0;i<n;i++){
29             fa[i]=i;
30             scanf("%d",&val[i]);
31         }
32         seek.clear();
33         int m;
34         scanf("%d",&m);
35         for(int i=0;i<m;i++){
36             scanf("%d %d",&fir[i].a,&fir[i].b);
37         }
38         int num;
39         scanf("%d",&num);
40         for(int i=0;i<num;i++){
41             char str[20];
42             scanf("%s",str);
43             if(str[0]=='q'){
44                 scanf("%d",&sec[i].a);
45                 sec[i].c=0;
46             }
47             else if(str[0]=='d'){
48                 scanf("%d%d",&sec[i].a,&sec[i].b);
49                 sec[i].c=1;
50                 seek[sec[i].a][sec[i].b]=1;
51                 seek[sec[i].b][sec[i].a]=1;
52             }
53         }
54         for(int i=0;i<m;i++){
55             if(seek[fir[i].a][fir[i].b]) continue;
56             add_edge( fir[i].a, fir[i].b);
57         }
58         for(int i=num-1;i>=0;i--){
59             if(sec[i].c==1){
60                 add_edge( sec[i].a, sec[i].b);
61             }
62             else {
63                 int sf=find_fa(sec[i].a);
64                 ans[i]=val[sf]>val[sec[i].a]?sf:-1;
65             }
66         }
67         for(int i=0;i<num;i++)
68             if(sec[i].c==0) printf("%d\n",ans[i]);
69     }
70     return 0;
71 }
 
 


猜你喜欢

转载自www.cnblogs.com/ZQUACM-875180305/p/9115041.html
ZOJ