제출 #1267809

#제출 시각아이디문제언어결과실행 시간메모리
1267809minhpkEvacuation plan (IZhO18_plan)C++20
100 / 100
445 ms97256 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a,b;
int c;
vector<pair<int,int>> z[100005];
int t[100005];
int cnt[100005];
int bruh=1e16;
void dijkstra(){
    for (int i=1;i<=a;i++){
         cnt[i]=bruh;
    }
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q;
    for (int i=1;i<=c;i++){
         q.push({0,t[i]});
         cnt[t[i]]=0;
    }
    while (q.size()){
         auto [val,pos]=q.top();
         q.pop();
         if (val>cnt[pos]){
             continue;
         }
         for (auto p:z[pos]){
              if (cnt[p.first]>val+p.second){
                  cnt[p.first]=val+p.second;
                  q.push({cnt[p.first],p.first});
              }
         }
    }
}
struct node{
      int x,y,val;
};
vector <node> v;
bool cmp(node a,node b){
     return a.val>b.val;
}
struct dsu{
      int par[100005];
      int sz[100005];
      void init(){
           for (int i=1;i<=a;i++){
                par[i]=i;
                sz[i]=1;
           }
      }
      int find(int u){
           if (par[u]==u){
               return u;
           }
           return par[u]=find(par[u]);
      }
      bool join(int x,int y){
           x=find(x);
           y=find(y);
           if (x==y){
               return false;
           }
           if (sz[x]<sz[y]){
               swap(x,y);
           }
           sz[x]+=sz[y];
           par[y]=x;
           return true;
      }
};
dsu d;
vector <pair<int,int>> z1[100005];
void krushkal(){
    int mst=0;
    for (auto p:v){
         if (d.join(p.x,p.y)){
//             cout << p.x << " " << p.y << " " << p.val << "\n";
             mst++;
             z1[p.x].push_back({p.y,p.val});
             z1[p.y].push_back({p.x,p.val});
         }
         if (mst==a-1){
             break;
         }
    }
}
int par[100005][21];
int cost[100005][21];
int high[1000005];
void dfs(int i,int parent){
     for (auto [p,w]:z1[i]){
          if (p==parent){
              continue;
          }
          high[p]=high[i]+1;
          par[p][0]=i;
          cost[p][0]=w;
          dfs(p,i);
     }
}
int lca(int x,int y){
    if (high[x]<high[y]){
        swap(x,y);
    }
    int cur=1e16;
    for (int i=20;i>=0;i--){
         if (high[par[x][i]]>=high[y]){
             cur=min(cur,cost[x][i]);
             x=par[x][i];
         }
    }
    if (x==y){
        return cur;
    }
    for (int i=20;i>=0;i--){
         if (par[x][i]!=par[y][i] && par[x][i]!=0){
             cur=min(cur,cost[x][i]);
             cur=min(cur,cost[y][i]);
             x=par[x][i];
             y=par[y][i];
         }
    }
    return min({cur,cost[x][0],cost[y][0]});
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> a >> b;
    for (int i=1;i<=b;i++){
         int x,y,t;
         cin >> x >> y >> t;
         z[x].push_back({y,t});
         z[y].push_back({x,t});
    }
    cin >> c;
    for (int i=1;i<=c;i++){
         cin >> t[i];
    }
    dijkstra();
//    for (int i=1;i<=a;i++){
//         cout << cnt[i] << " ";
//    }
//    cout << "\n";
    for (int i=1;i<=a;i++){
         for (auto [p,w]:z[i]){
              int val=min(cnt[p],cnt[i]);
              v.push_back({i,p,val});
         }
    }
    sort(v.begin(),v.end(),cmp);
    d.init();
    krushkal();
    high[0]=-1;
    dfs(1,0);
    for (int j=1;j<=20;j++){
         for (int i=1;i<=a;i++){
              par[i][j]=par[par[i][j-1]][j-1];
              cost[i][j]=min(cost[i][j-1],cost[par[i][j-1]][j-1]);
         }
    }
    int q;
    cin >> q;
    while (q--){
         int x,y;
         cin >> x >> y;
         cout << lca(x,y) << "\n";
    }
    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...