poj 2492 A Bug's Life 二分图染色 || 种类并查集

题目链接

题意

有一种\(bug\),所有的交往只在异性间发生。现给出所有的交往列表,问是否有可疑的\(bug\)(进行同性交往)。

思路

法一:种类并查集

参考:https://www.2cto.com/kf/201310/249052.html

对于每一个集合中的元素,用一个数组\(rank\)记录它和它的祖先性别是否相同,\(0\)为相同,\(1\)为不同。每个祖先的\(rank\)值为\(0\).

路径压缩时:rank[x] = rank[prev_fa]^rank[x];
因为是递归进行的路径压缩,所以更新\(x\)\(rank\)时,它之前父亲的\(rank\)值已经被更新过了,因为\(0\)表示相同,\(1\)表示不同,所以若\(rank[x]=0\),意味着\(x\)和它之前父亲的性别一样,其和新父亲的关系 和 原父亲与新父亲的关系 相同;若\(rank[x]=1\),意味着\(x\)和它之前父亲的性别不同,其和新父亲的关系 和 原父亲与新父亲的关系 不同。其实就是异或。

合并时:rank[xx]=!(rank[x]^rank[y]);
这里\(x\)的父亲为\(xx\)\(y\)的父亲为\(yy\). 若\(rank[x]==rank[y]\),因为\(x\)\(y\)性别不同,而\(x\)\(xx\)性别的关系与\(y\)\(yy\)性别的关系相同,所以\(xx\)\(yy\)性别不同;若\(rank[x]!=rank[y]\),因为\(x\)\(y\)性别不同,而\(x\)\(xx\)性别的关系与\(y\)\(yy\)性别的关系也不同,所以\(xx\)\(yy\)性别相同。其实就是同或。

法二:判断二分图

也可以用并查集写~

Code

Ver. 1

#include <stdio.h>
#include <iostream>
#define maxn 2010
using namespace std;
typedef long long LL;
int fa[maxn], rk[maxn], sz[maxn];
int find(int x) {
    if (fa[x] == x) return x;
    int tmp = fa[x];
    fa[x] = find(fa[x]);
    rk[x] = rk[tmp] ^ rk[x];
    return fa[x];
}
int kas;
void work() {
    printf("Scenario #%d:\n", ++kas);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) sz[i] = 1, fa[i] = i, rk[i] = 0;
    bool flag = false;
    for (int i = 0; i < m; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        if (flag) continue;
        int xx = find(x), yy = find(y);
        if (xx == yy) {
            if (rk[x] == rk[y]) flag = true;
        }
        else {
            if (sz[xx] > sz[yy]) swap(xx, yy), swap(x, y);
            fa[xx] = yy; rk[xx] = !(rk[x] ^ rk[y]); sz[yy] += sz[xx];
        }
    }
    if (flag) printf("Suspicious bugs found!\n\n");
    else printf("No suspicious bugs found!\n\n");
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) work();
    return 0;
}

Ver.2

#include <stdio.h>
#include <iostream>
#define maxn 4010
using namespace std;
typedef long long LL;
int fa[maxn], rk[maxn], sz[maxn];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void unionn(int x, int y) {
    x = find(x), y = find(y);
    if (sz[x] > sz[y]) swap(x, y);
    fa[x] = y, sz[y] += sz[x];
}
int kas;
void work() {
    printf("Scenario #%d:\n", ++kas);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= 2*n; ++i) sz[i] = 1, fa[i] = i;
    for (int i = 0; i < m; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        unionn(x, y+n), unionn(y, x+n);
    }
    bool flag = false;
    for (int i = 1; i <= n; ++i) if (find(i)==find(i+n)) { flag = true; break; }
    if (flag) printf("Suspicious bugs found!\n\n");
    else printf("No suspicious bugs found!\n\n");
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) work();
    return 0;
}

转载于:https://www.cnblogs.com/kkkkahlua/p/7659137.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值