제출 #1337761

#제출 시각아이디문제언어결과실행 시간메모리
1337761DangKhoizzzzEvacuation plan (IZhO18_plan)C++20
100 / 100
918 ms41092 KiB
#include <bits/stdc++.h>
#define int long long
#define arr3 array <int , 3>
#define pii pair <int , int>
#define fi first
#define se second
#define BIT(x , k) ((x >> k)&1)
#define MASK(x) (1 << x)

using namespace std;

const int maxn = 2e6 + 7;
const int INF = 1e8;

struct DSU
{
    vector <int> parent;
    DSU(int n) {parent.assign(n+5 , 0); iota(parent.begin() , parent.end() , 0);}
    int find_set(int u)
    {
        if(parent[u] == u) return u;
        return parent[u] = find_set(parent[u]);
    }
    void join(int u , int v)
    {
        u = find_set(u); v = find_set(v);
        if(u == v) return;
        parent[u] = v;
    }
    bool connected(int u , int v) {return find_set(u) == find_set(v);} 
};
int n , m , k , q , d[maxn] , L[maxn] , R[maxn] , ans[maxn];
vector <pii> g[maxn];
priority_queue <pii , vector <pii> , greater <pii>> Q;
vector <pii> ord , check;
pii ask[maxn];

void checker() // checker pita
{
    DSU dsu(n);
    vector <bool> open(n+5 , false);
    sort(check.begin() , check.end() , greater <pii> ());
    int cur = 0;
    for(auto [mid , i]: check)
    {
        while(cur < ord.size() && ord[cur].fi >= mid)
        {
            int u = ord[cur].se;
            open[u] = 1;
            for(auto[v , w]: g[u]) 
            {
                if(open[v]) dsu.join(u , v);
            }
            cur++;
        }
        if(dsu.connected(ask[i].fi , ask[i].se))
        {
            ans[i] = mid;
            L[i] = mid + 1;
        }
        else R[i] = mid - 1;
    }
}
void solve()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int u , v , w; cin >> u >> v >> w;
        g[u].push_back({v , w});
        g[v].push_back({u , w});
    }
    for(int i = 1; i <= n; i++) d[i] = INF;
    cin >> k;
    for(int i = 1; i <= k; i++)
    {
        int u; cin >> u;
        d[u] = 0;
        Q.push({0 , u});
    }
    while(!Q.empty())
    {
        int c = Q.top().fi , u = Q.top().se;
        Q.pop();
        if(c != d[u]) continue;
        ord.push_back({c , u});
        for(auto [v , w]: g[u])
        {
            if(d[v] > d[u] + w)
            {
                d[v] = d[u] + w;
                Q.push({d[v] , v});
            }
        }
    }
    reverse(ord.begin() , ord.end());
    cin >> q;
    for(int i = 1; i <= q; i++) 
    {
        cin >> ask[i].fi >> ask[i].se;
        ans[i] = 0;
        L[i] = 0;
        R[i] = INF;
    }
    for(int _ = 1; _ <= 31; _++)
    {
        check.clear();
        for(int i = 1; i <= q; i++)
        {
            if(L[i] > R[i]) continue;
            int mid = (L[i] + R[i])/2;
            check.push_back({mid , i});     
        }
        checker();
    }
    for(int i = 1; i <= q; i++) cout << ans[i] << '\n';
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr); solve();
    return 0;
}
#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...