您的位置:首页 > 其它

ZOJ 3261 Connections in Galaxy War(并查集)

2012-10-20 21:01 274 查看
转载请注明出处,谢谢/article/2566293.html
by---cxlove

题目:给出一些点,每个点有权值,然后有一些边,相连。无向的。然后有一些操作

query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大)

destory a,b 表示删除连接a,b的边

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3563

逆向并查集。

把没有删除的边先加入并查集,一个集合内表示连通的,根结点为权值最大的点。

然后对于查询离线读入,从最后开始操作,对于删除的点,然后重新加入到并查集中,更新最值。

查询的时候便是查询根结点的值是否大于自身的值

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<set>
#include<string>
#include<queue>
#define inf 1<<30
#define M 60005
#define N 605
#define maxn 300005
#define eps 1e-10
#define zero(a) fabs(a)<eps
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define lson step<<1
#define rson step<<1|1
#define MOD 1000000009
#define sqr(a) ((a)*(a))
using namespace std;
struct query
{
    int a,b,k;
}que[50005];
map<pair<int,int>,int>edge;
int pre[10005],num[10005],val[10005];
int n,m,q;
int find(int x)
{
    if(x!=pre[x])
    {
        int f=pre[x];
        pre[x]=find(pre[x]);
        num[x]=max(num[x],num[f]);
    }
    return pre[x];
}
void Union(int x,int y)
{
    int ra=find(x),rb=find(y);
    if(ra==rb) return;
    if(num[ra]>num[rb]||(num[ra]==num[rb]&&ra<rb))   pre[rb]=ra;
    else    pre[ra]=rb;
}
int main()
{
    int first=1;
    while(scanf("%d",&n)!=EOF)
    {
        if(!first) puts("");else first=0;
        for(int i=0;i<n;i++) scanf("%d",&val[i]);
        edge.clear();
        scanf("%d",&m);
        for(int i=0;i<n;i++) pre[i]=i,num[i]=val[i];
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            if(u>v) swap(u,v);
            edge[mp(u,v)]=1;
        }
        scanf("%d",&q);
        for(int i=0;i<q;i++)
        {
            char str[10];
            scanf("%s",str);
            if(str[0]=='q')
            {
                scanf("%d",&que[i].a);
                que[i].k=0;
            }
            else
            {
                scanf("%d%d",&que[i].a,&que[i].b);
                if(que[i].a>que[i].b) swap(que[i].a,que[i].b);
                edge[mp(que[i].a,que[i].b)]=0;
                que[i].k=1;
            }
        }
        map<pair<int,int>,int>::iterator it;
        for(it=edge.begin();it!=edge.end();it++)
        {
            if(it->second)
            {
                pair<int,int> tmp=it->first;
                Union(tmp.first,tmp.second);
            }
        }
        vector<int>ans;ans.clear();
        for(int i=q-1;i>=0;i--)
        {
            if(que[i].k==0)
            {
                if(num[find(que[i].a)]<=val[que[i].a]) ans.pb(-1);
                else ans.pb(find(que[i].a));
            }
            else   Union(que[i].a,que[i].b);
        }
        for(int i=ans.size()-1;i>=0;i--) printf("%d\n",ans[i]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: