【Code Force】Round #589 (Div. 2) D、Complete Tripartite

Topic link

General meaning

Divide a picture into three pieces, requiring that there is a complete picture between any two pieces, and there is no connection inside the block

analysis

First of all, it can be directly divided into two blocks according to the fact that there is no connection in the block.
Assuming that point 1 belongs to block 1, then all the points connected to point 1 do not belong to block 1; otherwise, it is block 1 and
then all the points that do not belong to block 1. Randomly find a point k in the point and set it to belong to block 2. Then all the points connected to point k that do not belong to block 1 are block 3.

The block is divided, and then to determine whether each block meets the conditions, I use the following three to determine

1. Each block has a point
2. There is no line inside each block, that is, the two end points of no line are in the same block.
3. The degree of the point in each block is equal to the number of points in the other two blocks. Also equal to n minus the number of points in the current block

AC Code

(Violence is over)

#include <bits/stdc++.h>

using namespace std;

#define MAXN 101000

int fa[MAXN];		// 保存了点属于哪个块
int deg[MAXN];		// 保存了点的度
pair<int, int> edge[MAXN * 3];

void solve() {
    
    
    int n, m;
    cin >> n >> m;
    int f2 = 2; // f2 用来找块2
    for (int i = 0; i < m; ++i) {
    
    
        int u, v;
        cin >> u >> v;
        deg[u]++;
        deg[v]++;
        edge[i] = {
    
    u, v};
        if (u == 1) {
    
    
            fa[v] = 1;
            f2 = v;
        } else if (v == 1) {
    
    
            fa[u] = 1;
            f2 = u;
        }
    }
    // 找出第三块
    for (int i = 0; i < m; ++i) {
    
    
        if (edge[i].first == f2 && fa[edge[i].second] == 1)
            fa[edge[i].second] = 2;
        else if (edge[i].second == f2 && fa[edge[i].first] == 1)
            fa[edge[i].first] = 2;
    }
    int cnt[3] = {
    
    n, n, n};	// 保存了每个块内点的个数
    // 需要变成完全图需要多少条边
    for (int i = 0; i < n; ++i)
        cnt[fa[i + 1]]--;
    // 块内的入度是否符合条件
    for (int i = 0; i < n; ++i) {
    
    
        if (deg[i + 1] != cnt[fa[i + 1]]) {
    
    
            cout << -1 << endl;
            return;
        }
    }
    // 每个块是否为空
    if (cnt[0] == n || cnt[1] == n || cnt[2] == n) {
    
    
        cout << -1 << endl;
        return;
    }
    // 内部连线
    for (int i = 0; i < m; ++i) {
    
    
        if (fa[edge[i].first] == fa[edge[i].second]) {
    
    
            cout << -1 << endl;
            return;
        }
    }
    for (int i = 0; i < n - 1; ++i)
        cout << fa[i + 1] + 1 << " ";
    cout << fa[n] + 1 << endl;
}

int main() {
    
    
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long long test_index_for_debug = 1;
    char acm_local_for_debug;
    while (cin >> acm_local_for_debug) {
    
    
        cin.putback(acm_local_for_debug);
        if (test_index_for_debug > 20) {
    
    
            throw runtime_error("Check the stdin!!!");
        }
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    }
#else
    solve();
#endif
    return 0;
}

In a word, violence is over. There are not many sides anyway, I am too lazy to optimize

Guess you like

Origin blog.csdn.net/m0_43448982/article/details/101787108