IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Codeforces 1444C 可撤销并查集 -> 正文阅读

[数据结构与算法]Codeforces 1444C 可撤销并查集

题意

传送门 Codeforces 1444C Team-Building

题解

图中节点划分为不相交的点集 S S S,求满足所构成子图为二分图的点集对 ( S 1 , S 2 ) (S_1,S_2) (S1?,S2?) 数量。

若点集 S S S 构成的子图存在奇环,则它与任意其他点集构成的子图都不可能是二分图。讨论满足二分图判定的点集即可。

若两点间存在一条边,则两点划分至不同的集合,可以通过并查集维护这样的关系。依次考虑点集 S S S,处理与它存在连边的点集 T T T,判断 S , T S,T S,T 构成的子图是否为二分图即可。可以用可撤销并查集维护这样的关系。

总时间复杂度 O ( m log ? n ) O(m\log n) O(mlogn)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int MAXN = 5E5 + 5;
int N, M, K, C[MAXN];
struct edge
{
    int u, v, id;
};
vector<edge> es[MAXN], es2[MAXN];

struct DSU
{
    int par[MAXN * 2], rnk[MAXN * 2], n;
    int stk[MAXN * 2][2], top;
    void init(int _n)
    {
        n = _n, top = 0;
        for (int i = 0; i < n; ++i)
            par[i] = i, rnk[i] = 0;
    }
    int find(int x) { return par[x] == x ? x : find(par[x]); }
    bool same(int x, int y) { return find(x) == find(y); }
    void merge(int x, int y)
    {
        x = find(x), y = find(y);
        if (x == y)
            return;
        if (rnk[x] > rnk[y])
            swap(x, y);
        int d = rnk[x] == rnk[y];
        stk[top][0] = x, stk[top++][1] = d;
        par[x] = y, rnk[y] += d;
    }
    void undo(int t)
    {
        while (top > t)
        {
            --top;
            int x = stk[top][0], d = stk[top][1];
            rnk[par[x]] -= d, par[x] = x;
        }
    }
} dsu;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> N >> M >> K;
    for (int i = 0; i < N; ++i)
        cin >> C[i], --C[i];
    for (int i = 0; i < M; ++i)
    {
        int u, v;
        cin >> u >> v;
        --u, --v;
        if (C[u] == C[v])
            es[C[u]].push_back({u, v, C[v]});
        else
        {
            if (C[u] < C[v])
                swap(u, v);
            es2[C[u]].push_back({u, v, C[v]});
        }
    }
    
    ll res = 0;
    dsu.init(2 * N);
    set<int> st;
    for (int i = 0; i < K; ++i)
    {
        bool ok = 1;
        for (auto &e : es[i])
        {
            int u = e.u, v = e.v;
            dsu.merge(u, N + v), dsu.merge(N + u, v);
            if (dsu.same(u, v) || dsu.same(N + u, N + v))
                ok = 0;
        }
        if (ok == 0)
            continue;
        set<int> st2;
        sort(es2[i].begin(), es2[i].end(), [](const edge &x, const edge &y)
             { return x.id < y.id; });
        for (int l = 0, r = 0, n = es2[i].size();l < n;)
        {
            while (r < n && es2[i][l].id == es2[i][r].id)
                ++r;
            int bg = dsu.top, g = es2[i][l].id;
            bool ok = 1;
            for (int j = l; j < r; ++j)
            {
                int u = es2[i][j].u, v = es2[i][j].v;
                dsu.merge(u, N + v), dsu.merge(N + u, v);
                if (dsu.same(u, v) || dsu.same(N + u, N + v))
                    ok = 0;
            }
            if (ok == 0)
                if (st.count(g))
                    st.erase(g), st2.insert(g);
            dsu.undo(bg);
            l = r;
        }
        res += st.size();
        for (int g : st2)
            st.insert(g);
        st.insert(i);
    }
    cout << res << '\n';
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 12:04:59  更:2022-04-28 12:06:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:32:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码