首页 > 技术文章 > “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)

zhuanzhuruyi 2016-12-25 19:47 原文

题意:初始时有个首都1,有n个操作

+V表示有一个新的城市连接到了V号城市

-V表示V号城市断开了连接,同时V的子城市也会断开连接

每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号最小的城市

输入数据保证正确,每次添加与删除的城市一定是与首都相连的

 

题解:每次都只需要知道最远且编号最小的城市,所以直接使用优先队列存储

如果是+V就使用并查集(不能路径压缩)添加上然后加入优先队列,接着直接弹出首元素就是结果

如果是-V则把V指向0,接着弹出优先队列的第一个元素

如果他与1相连就是答案,否则将他到0这条路上的点都连上0删除他,继续弹出

注意这儿有个trick就是如果没有城市与1相连,答案就是1

 

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=1<<28;
const ll INF=1ll<<60;
const double Pi=acos(-1.0);
const int Mod=1e9+7;
const int Max=2e5+7;
struct node
{
    int key,value;//存编号与离1的距离
    bool operator<(const node &c)const//距离大的编号小的优先
    {
        if(value==c.value)
            return key>c.key;
        return value<c.value;
    }
};
priority_queue<struct node> ans;
int fat[Max],val[Max];
char str[Max];
void Init(int n)
{
    while(!ans.empty())
        ans.pop();
        node temp;//初始化一个元素1在队列底部
        temp.value=0;
        temp.key=1;
        ans.push(temp);
    for(int i=0;i<=n;++i)
    {
        fat[i]=i;
        val[i]=0;
    }
    return;
}
int Find(int x)
{
    if(x==fat[x])
    return fat[x];
    return Find(fat[x]);
}
void Solveadd(int f,int s)//+
{
    node temp;

    fat[s]=f;
    val[s]=val[f]+1;

    temp.key=s;
    temp.value=val[s];
    ans.push(temp);

    return;
}
void Solvesub(int f)//-
{
    node temp;
    int s;
    fat[f]=0;
    while(!ans.empty())
    {
        temp=ans.top();
        if(Find(temp.key)==1)
            return;

            s=temp.key;
        while(fat[s]!=0)//链上赋为0
        {
            fat[s]=0;
        }
        ans.pop();
    }
    return;
}
int main()
{
int t,n,m,coun;
scanf("%d",&t);
node temp;
while(t--)
{
    scanf("%d",&n);
    Init(n+1);
    coun=1;
    for(int i=0;i<n;++i)
    {
        getchar();
        scanf("%c%d",&str[i],&m);
        if(str[i]=='+')
        {
            Solveadd(m,++coun);
        }
        else
        {
            Solvesub(m);
        }
            temp=ans.top();
        printf("%d\n",temp.key);
    }
}
return 0;
}

 

推荐阅读