ZOJ 3261 Connections in Galaxy War 并查集

将操作序列反向,用并查集维护集合里最强的星球。

--------------

const int maxn=11000;
const int maxm=22000;
const int maxq=55000;
int n,m,Q;
int p[maxn];
int a[maxn];
int id[maxn];
int pa[maxn];
void makeset(int n){
    for (int i=0;i<=n;i++) pa[i]=i;
}
int findset(int x){
    if (x!=pa[x]) pa[x]=findset(pa[x]);
    return pa[x];
}
void unionset(int x,int y){
    x=findset(x);
    y=findset(y);
    if (x!=y) {
        pa[x]=y;
        if (a[x]>a[y]){
            a[y]=a[x];
            id[y]=id[x];
        }
        else if (a[y]==a[x]&&id[x]<id[y]){
            id[y]=id[x];
        }
    }
}
struct Dat{
    int tp,x,y;
};
Dat q[maxq];
Dat e[maxm];
vector<int>ans;
set< PII >seto;
char s[10];
int main(){
    int cas=0;
    while (~scanf("%d",&n)){
        if (cas) printf("
");
        cas++;
        rst(q);
        rst(e);
        ans.clear();
        seto.clear();
        makeset(n);
        for (int i=0;i<n;i++){
            scanf("%d",&p[i]);
            a[i]=p[i];
            id[i]=i;
        }
        scanf("%d",&m);
        for (int i=0;i<m;i++) scanf("%d%d",&e[i].x,&e[i].y);
        scanf("%d",&Q);
        for (int i=0;i<Q;i++){
            scanf("%s",s);
            if (s[0]=='d'){
                q[i].tp=0;
                scanf("%d%d",&q[i].x,&q[i].y);
                seto.insert(make_pair(q[i].x,q[i].y));
                seto.insert(make_pair(q[i].y,q[i].x));
            }
            else if (s[0]=='q'){
                q[i].tp=1;
                scanf("%d",&q[i].x);
            }
        }
        for (int i=0;i<m;i++){
            if (seto.find(make_pair(e[i].x,e[i].y))==seto.end()){
                unionset(e[i].x,e[i].y);
            }
        }
        for (int i=Q-1;i>=0;i--){
            if (q[i].tp){
                int fa=findset(q[i].x);
                if (a[fa]>p[q[i].x]) ans.push_back(id[fa]);// printf("%d
",id[fa]);
                else ans.push_back(-1);// printf("-1
");
            }
            else{
                unionset(q[i].x,q[i].y);
            }
        }
        for (int i=sz(ans)-1;i>=0;i--){
            printf("%d
",ans[i]);
        }
        //printf("
");
    }

	return 0;
}


--------------

原文地址:https://www.cnblogs.com/cyendra/p/3681518.html