ZOJ 3261 (reverse union search) learned the usage of map+pair

Topic link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261

Drawing on the meaning of this big guy: https://www.cnblogs.com/cenariusxz/p/4792930.html

The meaning of the question: There are many planets, each with a force value, and there are some contact channels between the planets. Now there is a war, some contact channels will be destroyed, and some planets will be directly or indirectly contacted through the contact channels that have not been destroyed. If you arrive at the planet with the highest force value for help, if there are multiple ones with the highest force value, then contact the one with the lowest number. Now give a series of rescue and destruction sequences, execute it once, and find a suitable rescue planet number for each rescue command, if there is no one that can be rescued, output -1;
because the general union search set can only merge sets but cannot combine sets Detach, so it can be executed in reverse after offline, so that the detachment of the set becomes the merging of the set.

Just save all the edges and queries first, then mark all the destroyed channels, and then scan all the connection channel relationships, except the edges that will be destroyed, do not operate, and use the method of union search to establish the remaining connection channels stand up.

Since the value to be searched is the one with the largest force value and the smallest number, the one with the largest force value and the smallest number can be selected as the ancestor in the merge and search set.

Then, for all command sequences reversely processed, starting from the last one, the query will output the result directly. If the found ancestor node is itself, it will output -1. If the channel is destroyed, then the channel between these two points will be established. .

Code:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

#define mp(a,b) make_pair(a,b)
const int maxn =10000+5;

int N,p[maxn],M,Q,ans[maxn*5],fa[maxn],cnt;
char s[100];

map<pair<int,int>,int>edge;//记录边是否被摧毁

int find_(int x)
{
    return fa[x]==x? x: fa[x]=find_(fa[x]);
}

struct Edge
{
    int from,to;
} e[maxn*2];//所有的边

struct query
{
    int flag;
    int a,b;
    query()
    {
        b=0;
    }
} q[maxn*5];//查询

void unit(int x, int y)
{
    int u,v;
    u=find_(x);
    v=find_(y);
    if(u==v)
        return;
    if(p[u]>p[v])
    {
        fa[v]=u;
    }
    else if(p[u]<p[v])
    {
        fa[u]=v;
    }
    else if(p[u]==p[v])
    {
        if(u>v)
            fa[u]=v;
        else
            fa[v]=u;
    }
}

int main()
{
      int mk=0;
    while(scanf("%d",&N)!=EOF)
    {
        edge.clear();
        if(mk)
            printf("\n");
        mk=1;
        for(int i=0; i<N; i++)
        {
            scanf("%d",&p[i]);
            fa[i]=i;
        }
        scanf("%d",&M);
        int a,b;
        for(int i=0; i<M; i++)
        {
            scanf("%d%d",&a,&b);
            if(a>b)
                swap(a,b);
            e[i].from=a;
            e[i].to=b;
            edge[mp(a,b)]=1;
        }

        scanf("%d",&Q);

        for(int i=0; i<Q; i++)
        {
            scanf("\n%s ",s);
            if(s[0]=='q')
            {
                scanf("%d",&a);
                q[i].a=a;
                q[i].flag=0;
            }
            else if(s[0]=='d')
            {
                scanf("%d %d",&a,&b);
                if(a>b)
                    swap(a,b);
                q[i].a=a;
                q[i].b=b;
                q[i].flag=1;
                edge[mp(a,b)]=0;
            }
        }

        map<pair<int,int>,int>::iterator it;
        for(it=edge.begin(); it!=edge.end(); it++)
        {
            if(it->second)
            {
                pair<int,int> tmp=it->first;
                unit(tmp.first,tmp.second);
            }
        }

        cnt=Q;
        for(int i=Q-1; i>=0; i--)
        {
            if(q[i].flag==0)
            {
                cnt--;
                a=q[i].a;
                if(p[a]==p[find_(a)])
                    ans[cnt]=-1;
                else
                    ans[cnt]=find_(a);
            }
            else
            {
                a=q[i].a;
                b=q[i].b;
                unit(a,b);
            }
        }
        for(int i=cnt; i<Q; i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325950292&siteId=291194637