http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261
先把不需要destroy的边连上 然后逆序寻找答案 遇到destroy 的边就连上
过程中用并查集维护答案
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> #include<string> #include<queue> #include<stack> #include <iomanip> using namespace std; #define LL long long const double eps=1e-6; const int INF=0x3f3f3f3f; const int N=10005; const int M=50005; int a[N],f[N]; struct node { int l,r; }edge[M],Q[M]; int had[M]; typedef pair<int,int>pairedge; set<pairedge>st; int fx(int x) { if(f[x]!=x) f[x]=fx(f[x]); return f[x]; } void toge(int l,int r) { int L=fx(l); int R=fx(r); if(L!=R) { if(a[L]>a[R]||(a[L]==a[R]&&L<R)) f[R]=L; else f[L]=R; } } int main() { //freopen("data.in","r",stdin); int n; int I=0; while(scanf("%d",&n)!=EOF) { if(I++>0) printf("\n"); for(int i=0;i<n;++i) scanf("%d",&a[i]); int m; scanf("%d",&m); for(int i=0;i<m;++i) { scanf("%d %d",&edge[i].l,&edge[i].r); if(edge[i].l>edge[i].r) swap(edge[i].l,edge[i].r); } int q; scanf("%d",&q); st.clear(); for(int i=0;i<q;++i) { getchar(); char s[10]; scanf("%s",s); if(s[0]=='q') Q[i].l=-1; else scanf("%d",&Q[i].l); scanf("%d",&Q[i].r); if(Q[i].l!=-1) { if(Q[i].l>Q[i].r) swap(Q[i].l,Q[i].r); st.insert(pairedge(Q[i].l,Q[i].r)); } } for(int i=0;i<n;++i) f[i]=i; for(int i=0;i<m;++i) { if(st.find(pairedge(edge[i].l,edge[i].r))==st.end()) { toge(edge[i].l,edge[i].r); } } memset(had,0,sizeof(had)); for(int i=q-1;i>=0;--i) { if(Q[i].l!=-1) toge(Q[i].l,Q[i].r); else { Q[i].l=fx(Q[i].r); if(a[Q[i].l]>a[Q[i].r]) had[i]=1; else had[i]=-1; } } for(int i=0;i<q;++i) { if(had[i]==0) continue; if(had[i]==1) printf("%d\n",Q[i].l); else printf("-1\n"); } } return 0; }