제출 #1347169

#제출 시각아이디문제언어결과실행 시간메모리
1347169shirokitoEvacuation plan (IZhO18_plan)C++20
100 / 100
490 ms33436 KiB
#include <bits/stdc++.h>
using namespace std;

#define UP1(i, n) for (int i = 0; i < (n); i++)
#define UP2(i, a, b) for (int i = (a); i <= (b); i++)
#define UP3(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define DN1(i, n) for (int i = (n) - 1; i >= 0; i--)
#define DN2(i, a, b) for (int i = (a); i >= (b); i--)
#define DN3(i, a, b, c) for (int i = (a); i >= (b); i -= (c))
#define FOR_IMPL(_1, _2, _3, _4, NAME, ...) NAME
#define FOR_UP(...) FOR_IMPL(__VA_ARGS__, UP3, UP2, UP1) (__VA_ARGS__)
#define FOR_DN(...) FOR_IMPL(__VA_ARGS__, DN3, DN2, DN1) (__VA_ARGS__)

#define POPCOUNT(n) __builtin_popcountll(n)
#define CLZ(n) __builtin_clzll(n)
#define CTZ(n) __builtin_ctzll(n)
#define LOG(n) __lg(n)
#define BIT(n, i) (((n) >> (i)) & 1LL)
#define FLIP(n, i) ((n) ^ (1LL << (i)))
#define ON(n, i) ((n) | (1LL << (i)))
#define OFF(n, i) ((n) & ~(1LL << (i)))

#define all(x) (x).begin(), (x).end()
#define len(x) (int)x.size()

#define fi first
#define se second

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<long long, long long>;

#if __cplusplus <= 201402L
template <typename T> T gcd(T a, T b) { 
    return __gcd(a, b); 
}
template <typename T> T lcm(T a, T b) {
    return a / gcd(a, b) * b;
}
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
long long rand(long long l, long long r) {
    return uniform_int_distribution<long long>(l, r)(rng);  
}  

template <class T> void remove_duplicate(vector<T> &v) {
    sort(v.begin(), v.end()); 
    v.resize(unique(v.begin(), v.end()) - v.begin());
} 

template <class T> bool maximize(T &x, const T &y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
template <class T> bool minimize(T &x, const T &y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}  

const int N = 2e5 + 24;
const ll INF = 1e18;

int n, m, p, q; ll dist[N];
vector<pii> g[N];
pii qry[N]; int L[N], R[N]; ll ans[N];
vector<int> M[N];
bool used[N];

struct DSU {
    int n; vector<int> par, sz;

    DSU(int n_ = 0) { init(n_); }

    void init(int n_) {
        n = n_;
        par.resize(n + 1);
        sz.resize(n + 1);

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

    int find(int u) {
        return (u == par[u] ? u : par[u] = find(par[u]));
    }

    bool same(int u, int v) {
        return find(u) == find(v);
    }

    bool join(int u, int v) {
        u = find(u), v = find(v);

        if (u == v) return 0;

        if (sz[u] < sz[v]) swap(u, v);

        par[v] = u; 
        sz[u] += sz[v];

        return 1;
    }
} dsu;

int main() {
    cin.tie(0) -> sync_with_stdio(0);

    #define task "EXIT"
    if (fopen(task ".inp", "r")) {
        freopen(task ".inp", "r", stdin);
        freopen(task ".out", "w", stdout);
    }

    cin >> n >> m;

    FOR_UP (i, 1, m) {
        int u, v, w; cin >> u >> v >> w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }

    FOR_UP (i, 1, n) dist[i] = INF;

    multiset<pll> mts;

    cin >> p;
    while (p--) {
        int u; cin >> u; 
        dist[u] = 0; mts.insert({0, u});
    }

    while (len(mts)) {
        auto [_, u] = *mts.begin();
        mts.erase(mts.begin());

        for (auto [v, w]: g[u]) {
            if (minimize(dist[v], dist[u] + w)) {
                mts.insert({dist[v], v});
            }
        } 
    }

    vector<int> order; FOR_UP (i, 1, n) {
        order.push_back(i);
    }

    sort(all(order), [&](int i, int j) {
        return dist[i] > dist[j];
    });

    cin >> q;
    FOR_UP (i, 1, q) {
        cin >> qry[i].fi >> qry[i].se;
        if (qry[i].fi == qry[i].se) {
            ans[i] = dist[qry[i].fi];
            L[i] = 0, R[i] = -1;
        }
        else { L[i] = 0, R[i] = n - 1; } 
    }

    while (true) {
        FOR_UP (i, n) M[i].clear();
        FOR_UP (i, 1, n) used[i] = 0;
        
        bool run = 0;

        FOR_UP (i, 1, q) {
            if (L[i] > R[i]) continue;
            run = 1;
            int mid = (L[i] + R[i]) >> 1;
            M[mid].push_back(i);
        }

        if (!run) break;

        dsu.init(n);

        FOR_UP (i, n) {
            int u = order[i];
            used[u] = 1;
            
            for (auto [v, w]: g[u]) if (used[v]) {
                dsu.join(u, v);
            }

            for (int j: M[i]) {
                if (dsu.same(qry[j].fi, qry[j].se)) {
                    ans[j] = dist[u];
                    R[j] = i - 1;
                }
                else {
                    L[j] = i + 1;
                }
            }
        }
    }

    FOR_UP (i, 1, q) {
        cout << ans[i] << '\n';
    }
}

컴파일 시 표준 에러 (stderr) 메시지

plan.cpp: In function 'int main()':
plan.cpp:121:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  121 |         freopen(task ".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
plan.cpp:122:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  122 |         freopen(task ".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...