結果

問題 No.977 アリス仕掛けの摩天楼
ユーザー mencottonmencotton
提出日時 2020-11-02 22:34:58
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
CE  
(最新)
AC  
(最初)
実行時間 -
コード長 3,282 bytes
コンパイル時間 496 ms
コンパイル使用メモリ 69,080 KB
最終ジャッジ日時 2024-11-14 23:53:56
合計ジャッジ時間 1,044 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。

コンパイルメッセージ
main.cpp: In member function 'int LowLink<T>::dfs(int, int, int)':
main.cpp:89:31: error: there are no arguments to 'exchange' that depend on a template parameter, so a declaration of 'exchange' must be available [-fpermissive]
   89 |             if (to == par && !exchange(beet, true)) {
      |                               ^~~~~~~~
main.cpp:89:31: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
main.cpp: In instantiation of 'int LowLink<T>::dfs(int, int, int) [with T = int]':
main.cpp:73:31:   required from 'void LowLink<T>::build() [with T = int]'
main.cpp:125:12:   required from here
main.cpp:89:39: error: 'exchange' was not declared in this scope
   89 |             if (to == par && !exchange(beet, true)) {
      |                               ~~~~~~~~^~~~~~~~~~~~

ソースコード

diff #

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template<typename T = int>
struct Edge {
    int from, to;
    T cost;
    int idx;

    Edge() = default;

    Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}

    operator int() const { return to; }
};

template<typename T = int>
struct Graph {
    vector<vector<Edge<T>>> g;
    int es;

    Graph() = default;

    explicit Graph(int n) : g(n), es(0) {}

    size_t size() const {
        return g.size();
    }

    void add_directed_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es++);
    }

    void add_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }

    void read(int M, int padding = -1, bool weighted = false, bool directed = false) {
        for (int i = 0; i < M; i++) {
            int a, b;
            cin >> a >> b;
            a += padding;
            b += padding;
            T c = T(1);
            if (weighted) cin >> c;
            if (directed) add_directed_edge(a, b, c);
            else add_edge(a, b, c);
        }
    }
};

template<typename T = int>
using Edges = vector<Edge<T>>;

template<typename T = int>
struct LowLink : Graph<T> {
public:
    using Graph<T>::Graph;
    vector<int> ord, low, articulation;
    vector<Edge<T>> bridge;
    using Graph<T>::g;

    virtual void build() {
        used.assign(g.size(), 0);
        ord.assign(g.size(), 0);
        low.assign(g.size(), 0);
        int k = 0;
        for (int i = 0; i < (int) g.size(); i++) {
            if (!used[i]) k = dfs(i, k, -1);
        }
    }

    explicit LowLink(const Graph<T> &g) : Graph<T>(g) {}

private:
    vector<int> used;

    int dfs(int idx, int k, int par) {
        used[idx] = true;
        ord[idx] = k++;
        low[idx] = ord[idx];
        bool is_articulation = false, beet = false;
        int cnt = 0;
        for (auto &to : g[idx]) {
            if (to == par && !exchange(beet, true)) {
                continue;
            }
            if (!used[to]) {
                ++cnt;
                k = dfs(to, k, idx);
                low[idx] = min(low[idx], low[to]);
                is_articulation |= par >= 0 && low[to] >= ord[idx];
                if (ord[idx] < low[to]) bridge.emplace_back(to);
            } else {
                low[idx] = min(low[idx], ord[to]);
            }
        }
        is_articulation |= par == -1 && cnt > 1;
        if (is_articulation) articulation.push_back(idx);
        return k;
    }
};

int divide = 0;
vector<bool> visited;

void dfs(LowLink<> &g, int v) {
    for (auto &edge:g.g[v]) {
        if (!visited[edge.to]) {
            visited[edge.to] = true;
            dfs(g, edge.to);
        }
    }
}

int main() {
    int n;
    cin >> n;
    LowLink<> g(n);
    g.read(n - 1, 0);
    g.build();

    visited.resize(n);
    for (int i = 0; i < n; i++) {
        if (!visited[i]) {
            divide++;
            visited[i] = true;
            dfs(g, i);
        }
    }

    if (divide > 2)cout << "Alice" << endl;
    else if (divide == 2 && g.bridge.size())cout << "Alice" << endl;
    else cout << "Bob" << endl;
    return 0;
}
0