제출 #1332002

#제출 시각아이디문제언어결과실행 시간메모리
1332002kenkunkinEvacuation plan (IZhO18_plan)C++20
100 / 100
422 ms78204 KiB
#include <bits/stdc++.h>

using namespace std;

void Init()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

typedef long long ll;
typedef pair<ll,ll> pii;
ll n,m,k;
const int maxn=1e5+5,maxm=5e5+5;;

vector <pii> g[maxn];
priority_queue <pii,vector<pii>,greater<pii>> pq;
typedef pair<ll,pii> tri;
tri e[maxm];
ll d[maxn];
void Input()
{
    cin>>n>>m;
    for (int i=1;i<=m;i++)
    {
        ll u,v,w;
        cin>>u>>v>>w;
        e[i].second=pii(u,v);
        g[u].push_back({v,w});
        g[v].push_back({u,w});
    }
    for (int i=1;i<=n;i++)  d[i]=1e9;
    cin>>k;
    for (int i=1;i<=k;i++)
    {
        ll u;
        cin>>u;
        d[u]=0;
        pq.push({d[u],u});
    }

    while (!pq.empty())
    {
        pii tmp=pq.top();
        pq.pop();
        ll gt=tmp.first,u=tmp.second;
        if (gt>d[u]) continue;
        for (int i=0;i<g[u].size();i++)
        {
            ll v=g[u][i].first,w=g[u][i].second;
            if (d[v]>w+d[u])
            {
                d[v]=w+d[u];
                pq.push({d[v],v});
            }
        }
    }
}

ll p[maxn];

int findroot(int u)
{
    if (p[u]<=0)    return u;
    return p[u]=findroot(p[u]);
}

void Union(int u,int v)
{
    if (p[u]<p[v])
        p[v]=u;
    else
    {
        p[v]=min(p[v],p[u]-1);
        p[u]=v;
    }
}

vector <pii> adj[maxn];
void MST()
{
    for (int i=1;i<=m;i++)
    {
        auto [u,v]=e[i].second;
        e[i].first=min(d[u],d[v]);
    }
    sort(e+1,e+m+1,greater<tri>());

    for (int i=1;i<=m;i++)
    {
        auto [u,v]=e[i].second; ll w=e[i].first;
        int ru=findroot(u),rv=findroot(v);
        if (ru!=rv)
        {
            Union(ru,rv);
            adj[u].push_back({v,w});
            adj[v].push_back({u,w});
        }
    }
}

ll par[20][maxn],mn[20][maxn],dep[maxn];
bool check[maxn];
void DFS(int u)
{
    for (int i=0;i<adj[u].size();i++)
    {
        ll v=adj[u][i].first,w=adj[u][i].second;
        if (!check[v])
        {
            par[0][v]=u;
            mn[0][v]=w;
            dep[v]=dep[u]+1;
            check[v]=1;
            DFS(v);
        }
    }
}

ll query(int u,int v)
{
    ll ans=1e9;
    if (dep[u]>dep[v]) swap(u,v);
    int diff=dep[v]-dep[u];
    for (int i=17;i>=0;i--)
        if (diff>>i&1)
            ans=min(ans,mn[i][v]),v=par[i][v];
    if (u==v)   return ans;

    for (int i=17;i>=0;i--)
    {
        if (par[i][u]!=par[i][v])
        {
            ans=min({ans,mn[i][u],mn[i][v]});
            u=par[i][u],v=par[i][v];
        }
    }
    return min({ans,mn[0][u],mn[0][v]});
}

void Bai()
{
    for (int i=1;i<=17;i++)
        for (int j=0;j<=n;j++)
            mn[i][j]=1e9+5;
    MST();
    check[1]=1;
    DFS(1);
    for (int i=1;i<=17;i++)
        for (int j=1;j<=n;j++)
            par[i][j]=par[i-1][par[i-1][j]],mn[i][j]=min(mn[i-1][j],mn[i-1][par[i-1][j]]);

    int q;
    cin>>q;
    for (int i=1;i<=q;i++)
    {
        int u,v;
        cin>>u>>v;
        cout<<query(u,v)<<"\n";
    }


    return;
    for (int i=1;i<=n;i++)
    {
        cout<<i<<".";
        for (int j=0;j<adj[i].size();j++)
            cout<<adj[i][j].first<<" ";
        cout<<"\n";
    }
}


int main()
{
    Init();
    Input();
    Bai();
    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...