結果

問題 No.2072 Anatomy
ユーザー k1suxuk1suxu
提出日時 2022-09-16 22:57:46
言語 C++23(draft)
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 52 ms / 2,000 ms
コード長 5,306 bytes
コンパイル時間 4,368 ms
コンパイル使用メモリ 282,468 KB
実行使用メモリ 9,848 KB
最終ジャッジ日時 2023-08-23 16:27:01
合計ジャッジ時間 7,078 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,376 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 1 ms
4,376 KB
testcase_04 AC 2 ms
4,376 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 1 ms
4,380 KB
testcase_07 AC 2 ms
4,376 KB
testcase_08 AC 46 ms
9,160 KB
testcase_09 AC 45 ms
9,520 KB
testcase_10 AC 45 ms
7,652 KB
testcase_11 AC 47 ms
8,676 KB
testcase_12 AC 38 ms
7,772 KB
testcase_13 AC 50 ms
9,416 KB
testcase_14 AC 32 ms
6,608 KB
testcase_15 AC 29 ms
6,736 KB
testcase_16 AC 48 ms
9,136 KB
testcase_17 AC 47 ms
9,148 KB
testcase_18 AC 25 ms
6,308 KB
testcase_19 AC 50 ms
9,848 KB
testcase_20 AC 51 ms
9,264 KB
testcase_21 AC 48 ms
9,512 KB
testcase_22 AC 52 ms
9,244 KB
testcase_23 AC 49 ms
9,388 KB
testcase_24 AC 47 ms
9,208 KB
testcase_25 AC 51 ms
9,088 KB
testcase_26 AC 2 ms
4,380 KB
testcase_27 AC 48 ms
9,264 KB
testcase_28 AC 47 ms
9,388 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i = 0; i < (int)n; i++)
#define FOR(n) for(int i = 0; i < (int)n; i++)
#define repi(i,a,b) for(int i = (int)a; i < (int)b; i++)
#define pb push_back
#define all(x) x.begin(),x.end()
//#define mp make_pair
#define vi vector<int>
#define vvi vector<vi>
#define vll vector<ll>
#define vvll vector<vll>
#define vs vector<string>
#define vvs vector<vs>
#define vc vector<char>
#define vvc vector<vc>
#define pii pair<int,int>
#define pllll pair<ll,ll>
#define vpii vector<pair<int,int>>
#define vpllll vector<pair<ll,ll>>
#define vpis vector<pair<int,string>>
#define vplls vector<pair<ll, string>>
#define vpsi vector<pair<string, int>>
#define vpsll vector<pair<string, ll>>

template<typename T>
void chmax(T &a, const T &b) {a = (a > b? a : b);}
template<typename T>
void chmin(T &a, const T &b) {a = (a < b? a : b);}

using ll = long long;
using ld = long double;
using ull = unsigned long long;

const ll INF = numeric_limits<long long>::max() / 2;
const ld pi = 3.1415926535897932384626433832795028;
const ll mod = 998244353;
int dx[] = {-1, 0, 1, 0, -1, -1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 1};

#define int long long

//普通UnionFind -- Disjoing Set Union
struct UnionFind {
    vector<int> r;
    
    UnionFind(int n) {
        r = vector<int>(n, -1);
    }

    int root(int x) {
        if(r[x] < 0) return x;
        return r[x] = root(r[x]);
    }

    bool unite(pair<int, int> p) {
        return unite(p.first, p.second);
    }

    bool unite(int x, int y) {
        x = root(x);
        y = root(y);
        if(x == y) return false;
        if(r[x] > r[y]) swap(x, y);
        r[x] += r[y];
        r[y] = x;
        return true;
    }

    bool issame(pair<int, int> p) {
        return issame(p.first, p.second);
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    int size(int x) {
        return -r[root(x)];
    }

    int number_of_set() {
        set<int> st;
        FOR(r.size()) st.insert(root(i));
        return st.size();
    }
};

struct StronglyConnectedComponents {
    int n;
    //reversed_graph
    //辺を逆向きに貼りなおしたグラフ。
    vector<vector<int>> graph, reversed_graph;
    vector<int> order, component;
    vector<bool> used;
    void dfs(int v) {
        used[v] = 1;
        for(auto e : graph[v]) {
            if(used[e]) continue;
            dfs(e);
        }
        order.push_back(v);
    }
    void dfs2(int v, int k) {
        component[v] = k;
        for(auto e : reversed_graph[v]) {
            if(component[e] == -1) dfs2(e, k);
        }
    }

    StronglyConnectedComponents(vector<vector<int>> &G_) {
        n = G_.size();
        graph = G_;
        reversed_graph.resize(n);
        component.assign(n, -1);
        used.resize(n);
        for(int v = 0; v < n; v++) {
            for(auto e : graph[v]) reversed_graph[e].push_back(v);
        }
        for(int v = 0; v < n; v++) if(!used[v]) dfs(v);
        int k = 0;
        //topoogical sort in all the sub trees
        reverse(order.begin(), order.end());
        //いままでの強連結成分に含まれていなかったらDFS
        for(auto e : order) if(component[e] == -1) dfs2(e, k), k++;
    }

    //return if vertex(u, v) in same strongly connected component
    bool issame(int u, int v) {
        return component[u] == component[v];
    }

    vector<vector<int>> rebuild() {
        //コンポーネント数
        const int N = *max_element(component.begin(), component.end()) + 1;
        vector<vector<int>> rebuilded_graph(N);
        set<pair<int, int>> connected;
        for(int v = 0; v < N; v++) {
            for(auto e : graph[v]) {
                //同じ強連結成分に含まれていなくてかつ
                //その二つの強連結成分がグラフ上でつながれていなかったら
                if(component[v] != component[e] && !connected.count(make_pair(v, e))) {
                    connected.insert(make_pair(v, e));
                    rebuilded_graph[component[v]].push_back(component[e]);
                }
            }
        }
        return rebuilded_graph;
    }

    vector<vector<int>> pull_groups() {
        const int N = *max_element(component.begin(), component.end()) + 1;
        vector<vector<int>> groups;
        
        for(int i = 0; i < n; i++) {
            groups[component[i]].push_back(i);
        }

        return groups;
    }
};

void solve() {
    int n, m;
    cin >> n >> m;
    vpii edges;
    FOR(m) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        edges.emplace_back(u, v);
    }

    UnionFind UF(n);
    vector<int> ans(n, 0);
    reverse(all(edges));

    for(auto e : edges) {
        int r1 = UF.root(e.first);
        int r2 = UF.root(e.second);

        int nans = max({ans[r1], ans[r2], ans[e.first], ans[e.second]});
        ans[r1] = nans+1;
        ans[r2] = nans+1;
        ans[e.first] = nans+1;
        ans[e.second] = nans+1;
        
        UF.unite(e);
    }

    cout << *max_element(all(ans)) << endl;
}

signed main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    solve();
    return 0;
}
0