zoj3261变形并查集

需要变形的并查集,这题错了好久,一直没a掉,终于在重写第三次的时候a了

先保存数据,把不需要拆分的边合并,逆向计算,需要拆分时就合并,之前不知道为啥写搓了,tle好久

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 100000000
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define MIN(a,b) a<b ? a:b
#pragma comment(linker,"/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-9;
const int N=10000+10,maxn=500+10,inf=40000000;

int father[N],power[N];
vector<pair<int,int> >vec;
vector<int>v[N];
stack<int>s;

int Find(int x)
{
    return x!=father[x] ? Find(x=father[x]) : x;
}
void Merge(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    if(power[fx]>power[fy])father[fy]=fx;
    else if(power[fx]<power[fy])father[fx]=fy;
    else
    {
        if(fx<fy)father[fy]=fx;
        else father[fx]=fy;
    }
}
int main()
{
  /*  ios::sync_with_stdio(false);
    cin.tie(0);*/
    int n,m,k,c=0;
    while(~scanf("%d",&n)){
        if(c++)puts("");
        for(int i=0;i<n;i++)
        {
            scanf("%d",&power[i]);
            v[i].clear();
            father[i]=i;
        }
        vec.clear();
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a>b)swap(a,b);
            v[a].push_back(b);
        }
        scanf("%d",&k);
        while(k--){
            char p[10];
            scanf("%s",&p);
            if(p[0]==‘d‘)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                if(a>b)swap(a,b);
                for(int i=0;i<v[a].size();i++)
                    if(v[a][i]==b)
                       v[a][i]=-1;
                vec.push_back(make_pair(a,b));
            }
            else
            {
                int a;
                scanf("%d",&a);
                vec.push_back(make_pair(-1,a));
            }
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<v[i].size();j++)
                if(v[i][j]!=-1)
                  Merge(i,v[i][j]);
        for(int i=vec.size()-1;i>=0;i--)
        {
            if(vec[i].first==-1)
            {
                int ans=Find(vec[i].second);
                if(power[ans]>power[vec[i].second])s.push(ans);
                else s.push(-1);
            }
            else Merge(vec[i].first,vec[i].second);
        }
        while(!s.empty()){
            printf("%d\n",s.top());
            s.pop();
        }
    }
    return 0;
}

时间: 2024-08-10 23:26:33

zoj3261变形并查集的相关文章

并查集&amp;MST

[HDU] 1198 Farm Irrigation 基础最小生成树★ 1598 find the most comfortable road 枚举+最小生成树★★ 1811 Rank of Tetris 并查集+拓扑排序★★ 3926 Hand in Hand 同构图★ 3938 Portal 离线+并查集★★ 2489     Minimal Ratio Tree dfs枚举组合情况+最小生成树★ 4081     Qin Shi Huang's National Road System 最

poj2492--A Bug&#39;s Life(并查集变形)

A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28703   Accepted: 9350 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders

poj2492--A Bug&amp;#39;s Life(并查集变形)

A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28703   Accepted: 9350 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders

zoj3261 带权并查集

题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现在发生战争,有一些联系通道会被摧毁,而一些星球会通过还没有被摧毁的联系通道直接或者间接联系能够联系到的武力值最高的星球求救,如果有多个武力值都为最高的,那就联系一个编号最小的.现在给出一系列求救和摧毁的序列,一次执行,并对于每一个求救指令寻找合适的求救星球编号,如果没有可以求救的则输出 -1: 由于一般并查集只能够合并集合而不能将集合拆离,因此可以离线之后反向执行,这样集合的拆离就变成了集合的合并. 只要先保存所有的边和询问,然后对于所有

acdream 1685 多民族王国(图,DFS,并查集变形)

Problem Description 娜娜好不容易才回忆起自己是娜娜而不是什么Alice,也回忆起了自己要继续探索这个世界的目标,便偷偷溜出皇宫.娜娜发现这个王国有很多个民族组成,每个民族都有自己的方言,更要命的是这些方面差别还很远,这就导致这个王国的人民交流十分困难.娜娜仔细观察并记录了好久,发现总共有m种不同的语言. 突然娜娜发现前面有一群天才在讨论问题,但是奈何语言问题,导致这群人交流非常吃力.不过幸亏的是,这群天才都有一个特殊的能力,只要消耗一个单位的能量即可完全领悟一门新的语言(妈妈

BZOJ 3674 可持久化并查集加强版(主席树变形)

3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2515  Solved: 1107 [Submit][Status][Discuss] Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2*10^4 Input Output Sample Inp

POJ 1182 (经典食物链 /并查集扩展)

(參考他人资料) 向量偏移--由"食物链"引发的总结 http://poj.org/problem?id=1182这道食物链题目是并查集的变型.非常久曾经做的一次是水过的,这次细致地研究了这"食物链",无非就是运用向量偏移.从曾经节点与节点转化成向量与向量的关系.我们能够把矛盾的产生得益于向量偏移时的结果. 直接引出向量偏移的运用. 以下是POJ一位大牛这样理解的,本人稍有改动. 对于集合里的随意两个元素a,b而言,它们之间必然存在着某种联系,由于并查集中的元素

并查集——向量偏移

让我们用一道题来说明这个问题吧 题目连接:http://poj.org/problem?id=1182 我们先不妨假设a与b是同类的时候偏移量为0 a吃b的时候偏移量1 a被b吃的时候偏移量为2   a的父亲节点为aa b的父亲节点为bb 有了这个假设,那下面就能很方便解决这个问题了 我们先查找给出节点的父亲节点然后看看父亲节点的是不是相同的 如果是不相同的那么我们就更新b的父亲节点的偏移量 先看一张图片 由图片可知   p[fx].relation = (3 + p[y].relation -

HDU 1181 并查集 or SPFA

变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 12773    Accepted Submission(s): 4733 Problem Description 呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规