0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【AtCoder】CODE FESTIVAL 2016 Final C - Interpretation

Last updated at Posted at 2019-03-12

CODE FESTIVAL 2016 Final C - Interpretation

問題概要

C - Interpretation

解法

愚直に全ての人の間に辺を貼ろうとすると$O(N^2)$となるため間に合わない。そこで、人$i$と言語$L_{ij}$の二部グラフを作り、人$i$が話せる言語$L_{ij}$に対して辺を貼る。このグラフにおいて、全ての人が連結であれば答えはYES、連結でなければ答えはNO。連結判定にはUnionFind等を使えばよい。計算量は$O(N + M)$で十分高速である。

ソースコード

#include <bits/stdc++.h>

using namespace std;

#define llong long long int
#define ldouble long double
#define rep(i, n) for (int i = 0; i < n; ++i)
#define all(x) x.begin(), x.end()
#define allr(x) x.rbegin(), x.rend()
#define stl_rep(itr, x) for (auto itr = x.begin(); itr != x.end(); ++itr)

const static llong MOD = 1000000000 + 7;
const static llong INF = 1LL << 60;
const static double eps = 1e-6;
const static int dy[] = {0, 1, 0, -1};
const static int dx[] = {1, 0, -1, 0};

template<typename T> T my_gcd(T a, T b) {
    return (a ? my_gcd(b % a, a) : b);
}

template<typename T> T my_lcm(T a, T b){
	return a * b / my_gcd(a, b);	
}

template<typename T> struct UF {
    vector<int> par;
    vector<T> sz;

    UF(int n) {
        par.resize(n);
        sz.resize(n);
        for (int i = 0; i < n; ++i) {
            par[i] = i;
            sz[i] = 1;
        }
    }

    int find_root(int x) {
        return par[x] == x ? x : par[x] = find_root(par[x]);
    }

    bool same(int x, int y) {
        return find_root(x) == find_root(y);
    }

    void unite(int x, int y) {
        x = find_root(x);
        y = find_root(y);
        if (x == y) return;
        
        if (sz[x] < sz[y]) swap(x, y);
        sz[x] += sz[y];
        par[y] = x;
    }

    T size_of_tree(int x) {
        return sz[find_root(x)];
    }
};

signed main (int argc, char *argv[]) {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    UF<int> uf(n + m);
    rep(i, n) {
        int k;
        cin >> k;
        rep(j, k) {
            int l;
            cin >> l;
            uf.unite(l - 1, m + i);
        }
    }

    bool flag = true;
    rep(i, n - 1) {
        if (! uf.same(m + i, m + i + 1)) {
            flag = false;
            break;
        }
    }

    if (flag) cout << "YES" << endl;
    else cout << "NO" << endl;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?