noj1044(并查集)

题目描述

给定一个无向图,一共n个点,请编写一个程序实现两种操作:

D x y 从原图中删除连接x,y节点的边。

Q x y 询问x,y节点是否连通



输入

第一行两个数n,m(5<=n<=40000,1<=m<=100000)

接下来m行,每行一对整数 x y (x,y<=n),表示x,y之间有边相连。保证没有重复的边。

接下来一行一个整数 q(q<=100000)

以下q行每行一种操作,保证不会有非法删除。

输出

按询问次序输出所有Q操作的回答,连通的回答C,不连通的回答D

样例输入

3 3
1 2
1 3
2 3
5
Q 1 2
D 1 2
Q 1 2
D 3 2
Q 1 2

样例输出

C
C

D

关键在于直接删除边比较麻烦,所以提前读后面的操作,看看有哪些边剩下来,把那些边先组合,最后从后往前一旦遇到操作是删除边的就把边加上去,这样就将删除边转化成并查集的添加边.还有一个关键是判断那些边剩下,用a*MAX+b即可,这样可以直接通过判断book[a*MAX+b]是不是为真,得知a,b是否还存留(而不是被删掉).

之前没有用map,不知道怎么处理,后来看了明神的,所以直接上他的代码了.

#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
int const MAX = 100005;
int n, m, fa[MAX];
char ans[MAX];
struct EDGE
{
    int u, v;
    bool d;
}e[MAX], q[MAX];
map<int, bool> hash;

void UF_set()
{
    for(int i = 0; i <= MAX; i++)
        fa[i] = i;
}

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

void Union(int a, int b)
{
    int r1 = Find(a);
    int r2 = Find(b);
    if(r1 != r2)
        fa[r2] = r1;
}

int main()
{
    UF_set();
    scanf("%d %d", &n, &m);
    for(int i = 0; i < m; i++)
    {
        scanf("%d %d", &e[i].u, &e[i].v);
        if(e[i].u > e[i].v)
            swap(e[i].u, e[i].v);
    }
    int qnum;
    char s[2];
    scanf("%d", &qnum);
    for(int i = 0; i < qnum; i++)
    {
        scanf("%s %d %d", s, &q[i].u, &q[i].v);
        if(q[i].u > q[i].v)
            swap(q[i].u, q[i].v);
        if(s[0] == 'D')
        {
            q[i].d = true;
            hash[q[i].u * MAX + q[i].v] = true;
        }
        else
            q[i].d = false;
    }
    for(int i = 0; i < m; i++)
        if(!hash[e[i].u * MAX + e[i].v])
            Union(e[i].u, e[i].v);
    int cnt = 0;
    for(int i = qnum - 1; i >= 0; i--)
    {
        if(q[i].d)
            Union(q[i].u, q[i].v);
        else
        {
            if(Find(q[i].u) == Find(q[i].v))
                ans[cnt++] = 'C';
            else
                ans[cnt++] = 'D';
        }
    }
    for(int i = cnt - 1; i >= 0; i--)
        printf("%c\n", ans[i]);
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值