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;
}
浙公网安备 33010602011771号