zoukankan      html  css  js  c++  java
  • codeforces 1228D Complete Tripartite(图论+思维)

    传送门

    题意:给定一张不保证联通的简单图,问是否存在染色方案,使得每一个连通块为三分图。

    分析:不考虑其他约束,只考虑三分图每一个子集内部没有边相连的约束,先染出一张图。做法为首先对于一个连通块,先选定一个起点u,将u染成1,然后将与u直接相连的点,全部染成2,然后选择一个染成2的点为v,然后将所有与v直接相连的点w染色,其中如果w未染色,那么将w染成1,如果w被染成2,将w染成3。然后再判断这个染色的图是否符合条件。

    对于所有的联通块,维护连通块内三种色块中点的数量,如果有一个联通块的某一种色块数量为0,说明连通块内凑不满三个子集,不合法。

    对于一个点,如果他直接连接的点数为当前联通块其他两种颜色点的数量之和,则合法,否则不合法。

    对于一条边,如果联通颜色相同的点,不合法。

    代码中的判断可能有冗余。

    代码:

    #include <bits/stdc++.h>
    #define mp make_pair
    #define debug(x) cout << #x << ": " << x << endl
    #define pb push_back
    typedef long long LL;
    const int maxn = 3e5 + 10;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    using namespace std;
    int n, m, u, v, col[maxn], f[maxn], sz[maxn];
    int find(int x) {
        return f[x] == -1 ? x : f[x] = find(f[x]);
    }
    vector<int> g[maxn];
    vector<int> s[maxn][3];
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin >> n >> m;
        for (int i = 0; i < m; ++i) {
            cin >> u >> v;
            g[u].pb(v);
            g[v].pb(u);
        }
        for (int i = 1; i <= n; ++i)
            f[i] = -1;
        for (int i = 1; i <= n; ++i) {
            if (col[i] == 0) {
                col[i] = 1;
                int fu = find(i);
                if (g[i].empty()) {
                    cout << -1;
                    exit(0);
                }
                int to = g[i][0];
                for (int j = 0; j < g[i].size(); ++j) {
                    int _to = g[i][j];
                    int fv = find(_to);
                    if (fv != fu)
                        f[fv] = fu;
                    col[_to] = 2;
                }
                for (int j = 0; j < g[to].size(); ++j) {
                    int _to = g[to][j];
                    if (_to == i)
                        continue;
                    int fv = find(_to);
                    if (fv != fu)
                        f[fv] = fu;
                    if (col[_to] == 0)
                        col[_to] = 1;
                    else if (col[_to] == 2)
                        col[_to] = 3;
                    else {
                        cout << -1;
                        exit(0);
                    }
                }
            }
        }
        for (int i = 1; i <= n; ++i) {
            v = find(i);
            s[v][col[i] - 1].pb(i);
        }
        for (int i = 1; i <= n; ++i)
            if (!s[i][0].empty() || !s[i][1].empty() || !s[i][2].empty()) {
                if (s[i][0].empty() || s[i][1].empty() || s[i][2].empty()) {
                    cout << -1;
                    exit(0);
                }
            }
        for (int i = 1; i <= n; ++i) {
            v = find(i);
            if (col[i] == 1) {
                if (s[v][1].size() + s[v][2].size() != g[i].size()) {
                    cout << -1;
                    exit(0);
                }
            }
            else if (col[i] == 2) {
                if (s[v][0].size() + s[v][2].size() != g[i].size()) {
                    cout << -1;
                    exit(0);
                }
            }
            else if (col[i] == 3) {
                if (s[v][0].size() + s[v][1].size() != g[i].size()) {
                    cout << -1;
                    exit(0);
                }
            }
            for (int j = 0; j < g[i].size(); ++j) {
                int to = g[i][j];
                if (col[to] == col[i]) {
                    cout << -1;
                    exit(0);
                }
            }
        }
        for (int i = 1; i <= n; ++i)
            cout << col[i] << " ";
    }
    View Code
  • 相关阅读:
    数据库中的字段NULL值和''
    MySQL Notifier
    LeetCode算法题-Delete Node in a Linked List(Java实现)
    LeetCode算法题-Lowest Common Ancestor of a Binary Search Tree
    LeetCode算法题-Palindrome Linked List(Java实现)
    LeetCode算法题-Implement Queue Using Stacks(Java实现)
    LeetCode算法题-Power Of Two(Java实现)
    LeetCode算法题-Invert Binary Tree
    LeetCode算法题-Implement Stack Using Queues
    LeetCode算法题-Contains Duplicate II(Java实现)
  • 原文地址:https://www.cnblogs.com/smallhester/p/11610616.html
Copyright © 2011-2022 走看看