分析:对于这种删边操作,我们通常可以先读进来,然后转化离线进行倒着加边
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; typedef pair<int,int>pii; const int N=1e4+5; pii p[N<<1]; int v[N],fa[N],n,m,q; bool vis[N<<1]; struct Ask{ int op,id,ans; }ask[N*5]; int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); } void Union(int x,int y){ x=find(x),y=find(y); if(x==y)return; if(v[x]>v[y]||(v[x]==v[y]&&x<y))fa[y]=x; else fa[x]=y; } int main() { bool flag=1; while(~scanf("%d",&n)){ if(flag)flag=0; else printf("\n"); for(int i=0;i<n;++i){ scanf("%d",&v[i]),fa[i]=i; } memset(vis,0,sizeof(vis)); scanf("%d",&m); for(int i=1;i<=m;++i){ scanf("%d%d",&p[i].first,&p[i].second); if(p[i].first>p[i].second)swap(p[i].first,p[i].second); } sort(p+1,p+1+m); scanf("%d",&q); for(int i=1;i<=q;++i){ char s[10]; int u,v; scanf("%s%d",s,&u); if(s[0]=='q'){ ask[i].op=1; ask[i].id=u; } else{ ask[i].op=2; scanf("%d",&v); if(u>v)swap(u,v); ask[i].id=lower_bound(p+1,p+1+m,make_pair(u,v))-p; vis[ask[i].id]=1; } } for(int i=1;i<=m;++i){ if(vis[i])continue; Union(p[i].first,p[i].second); } for(int i=q;i>0;--i){ if(ask[i].op==1){ ask[i].ans=find(ask[i].id); if(v[ask[i].ans]==v[ask[i].id])ask[i].ans=-1; } else Union(p[ask[i].id].first,p[ask[i].id].second); } for(int i=1;i<=q;++i)if(ask[i].op==1)printf("%d\n",ask[i].ans); } return 0; }