题目链接: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 ",ans[i]); 69 } 70 return 0; 71 }