zoj 3261 逆向并查集+离线处理
题意:给出一些点,每个点有权值,然后有一些边,相连。无向的。然后有一些操作
链接:点我
query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大)
destory a,b 表示删除连接a,b的边
逆向并查集。
把没有删除的边先加入并查集,一个集合内表示连通的,根结点为权值最大的点。
然后对于查询离线读入,从最后开始操作,对于删除的点,然后重新加入到并查集中,更新最值。
查询的时候便是查询根结点的值是否大于自身的值
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 #include <map> 6 using namespace std; 7 8 const int MAXN=10010; 9 int F[MAXN]; 10 int p[MAXN]; 11 int val[MAXN];//最大值的下标 12 int num[MAXN];//最大值 13 int find(int x) 14 { 15 if(F[x]==-1)return x; 16 return F[x]=find(F[x]); 17 } 18 void bing(int u,int v) 19 { 20 int t1=find(u),t2=find(v); 21 if(t1!=t2) 22 { 23 F[t1]=t2; 24 if(num[t1]>num[t2]) 25 { 26 num[t2]=num[t1]; 27 val[t2]=val[t1]; 28 } 29 else if(num[t1]==num[t2] && val[t2]>val[t1]) 30 val[t2]=val[t1]; 31 } 32 } 33 map<int,int>mp[MAXN]; 34 struct Edge 35 { 36 int u,v; 37 }edge[20010]; 38 bool used[20010]; 39 struct Node 40 { 41 int op; 42 int u,v; 43 }node[50010]; 44 int ans[50010]; 45 char str[20]; 46 int main() 47 { 48 int n; 49 int Q; 50 int m; 51 int u,v; 52 bool first=true; 53 while(scanf("%d",&n)==1) 54 { 55 if(first)first=false; 56 else printf("\n"); 57 memset(F,-1,sizeof(F)); 58 for(int i=0;i<n;i++) 59 { 60 scanf("%d",&p[i]); 61 val[i]=i; 62 num[i]=p[i]; 63 mp[i].clear(); 64 } 65 66 scanf("%d",&m); 67 for(int i=0;i<m;i++) 68 { 69 scanf("%d%d",&u,&v); 70 if(u>v)swap(u,v); 71 mp[u][v]=i; 72 edge[i].u=u; 73 edge[i].v=v; 74 used[i]=false; 75 } 76 scanf("%d",&Q); 77 for(int i=0;i<Q;i++) 78 { 79 scanf("%s",&str); 80 if(str[0]=='q') 81 { 82 node[i].op=0; 83 scanf("%d",&node[i].u); 84 } 85 else 86 { 87 node[i].op=1; 88 scanf("%d%d",&u,&v); 89 if(u>v)swap(u,v); 90 node[i].u=u; 91 node[i].v=v; 92 int tmp=mp[u][v]; 93 used[tmp]=true; 94 } 95 } 96 for(int i=0;i<m;i++) //没有拆的点连上 97 if(!used[i]) 98 { 99 bing(edge[i].u,edge[i].v); 100 } 101 int cnt=0; 102 for(int i=Q-1;i>=0;i--) 103 { 104 if(node[i].op==0) 105 { 106 u=node[i].u; 107 int t1=find(u); 108 if(num[t1]>p[u])ans[cnt++]=val[t1]; 109 else ans[cnt++]=-1; 110 } 111 else 112 { 113 bing(node[i].u,node[i].v); 114 } 115 } 116 for(int i=cnt-1;i>=0;i--)printf("%d\n",ans[i]); 117 } 118 return 0; 119 }