Submission #1350961

#TimeUsernameProblemLanguageResultExecution timeMemory
1350961dex111222333444555Evacuation plan (IZhO18_plan)C++20
100 / 100
236 ms53936 KiB
#include <bits/stdc++.h>
#define all(v) begin(v), end(v)
#define dbg(x) "[" #x " = " << x << "]"
#define ii pair<int, long long>
#define fi first
#define se second
#define siz(v) (int)(v).size()
#define lli pair<long long, int>
#define BIT(x, i) (((x) >> (i)) & 1)

using namespace std;

const int infINT = 1e9 + 1323;
const long long inf = 1e18 + 123123;

template<class X, class Y> bool minimize(X &x, const Y &y){return x > y ? x = y, 1: 0;}
template<class X, class Y> bool maximize(X &x, const Y &y){return x < y ? x = y, 1: 0;}

struct E{
    int u, v;
    long long w;

    E(int _u = 0, int _v = 0, long long _w = 0):
        u(_u), v(_v), w(_w) {};

    bool operator <(const E &other) const{
        return w > other.w;
    }
};

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

    dsu(int _n = 0): n(_n){
        par.assign(n + 1, 0);
        sz.assign(n + 1, 1);
        for(int i = 1; i <= n; i++) par[i] = i;
    }

    int root(int v){
        return v == par[v] ? v: par[v] = root(par[v]);
    }

    bool join(int u, int v){
        u = root(u), v = root(v);
        if (u == v) return 0;
        if (sz[u] < sz[v]) swap(u, v);
        par[v] = u; sz[u] += sz[v];
        return 1;
    }
};

const int MAXN = 1e5 + 5, MAXM = 2e5 + 5, LOG = 18;

int numNode, numEdge, numDanger, numQuery, danger[MAXN], up[LOG][MAXN], h[MAXN];
long long dist[MAXN], minVal[LOG][MAXN];
E edge[MAXN];
vector<ii > adj[MAXN];

void input(){
    cin >> numNode >> numEdge;
    for(int i = 1; i <= numEdge; i++){
        int u, v, w; cin >> u >> v >> w;
        adj[u].emplace_back(v, w);
        adj[v].emplace_back(u, w);
        edge[i] = E(u, v, w);
    }

    cin >> numDanger;
    for(int i = 1; i <= numDanger; i++) cin >> danger[i];
}

void dijsktra(){
    priority_queue<lli, vector<lli>, greater<lli > > q;
    memset(dist, 0x3f, sizeof dist);
    for(int i = 1; i <= numDanger; i++){
        q.emplace(dist[danger[i]] = 0, danger[i]);
    }

    while(siz(q)){
        int u = q.top().se;
        long long len = q.top().fi;

        q.pop();

        if (len > dist[u]) continue;

        for(ii x: adj[u]){
            int v = x.fi, w = x.se;
            if (minimize(dist[v], dist[u] + w)) q.emplace(dist[v], v);
        }
    }
}

void dfs(int u, int par = 0){
    for(ii x: adj[u]) if (x.fi != par) {
        int v = x.fi;
        long long w = x.se;

        up[0][v] = u;
        minVal[0][v] = w;

        for(int i = 1; i < LOG; i++){
            up[i][v] = up[i - 1][up[i - 1][v]];
            minVal[i][v] = min(minVal[i - 1][v], minVal[i - 1][up[i - 1][v]]);
        }

        h[v] = h[u] + 1;

        dfs(v, u);
    }
}

long long getMin(int u, int v){
    if (h[u] < h[v]) swap(u, v);
    int k = h[u] - h[v];

    long long mi = dist[u];

    for(int i = LOG - 1; i >= 0; i--) if (BIT(k, i)) {
        mi = min(mi, minVal[i][u]);
        u = up[i][u];
    }

    if (u == v) return mi;

    for(int i = LOG - 1; i >= 0; i--) if (up[i][u] != up[i][v]){
        mi = min(mi, min(minVal[i][u], minVal[i][v]));
        u = up[i][u]; v = up[i][v];
    }

    mi = min(mi, min(minVal[0][u], minVal[0][v]));

    return mi;
}

void solve(){
    dijsktra();

    for(int u = 1; u <= numNode; u++){
        adj[u].clear();
    }

    for(int i = 1; i <= numEdge; i++){
        int &u = edge[i].u, &v = edge[i].v;
        long long &w = edge[i].w;
        w = min(dist[u], dist[v]);
    }

    sort(edge + 1, edge + 1 + numEdge);

    dsu mySet(numNode);

    for(int i = 1; i <= numEdge; i++){
        int &u = edge[i].u, &v = edge[i].v;
        long long &w = edge[i].w;
        if (mySet.join(u, v)){
            adj[u].emplace_back(v, w);
            adj[v].emplace_back(u, w);
        }
    }

    dfs(1);

    cin >> numQuery;

    for(int q = 1; q <= numQuery; q++){
        int sta, fin; cin >> sta >> fin;
        cout << getMin(sta, fin) << '\n';
    }
}

bool M1;

bool M2;
signed main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #define task "EXIT"
    if (fopen(task".inp", "r")){
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }
    input();
    solve();
    cerr << (&M2 - &M1) / 1048576 << " mb\n";
    cerr << (1.0 * clock()) / CLOCKS_PER_SEC << ".s\n";
}

Compilation message (stderr)

plan.cpp: In function 'int main()':
plan.cpp:181:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  181 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
plan.cpp:182:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  182 |         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...