This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
#define f first
#define s second
const int maxn = 100001;
const int oo = 1e9;
const int mx2 = 18;
int st[2][mx2][maxn];
int n, m, k, q;
void build(int x){
if(x == mx2)return;
for(int i = 1; i <= n; i++){
if(st[0][x-1][i] != -1){
st[0][x][i] = st[0][x-1][st[0][x-1][i]];
st[1][x][i] = min(st[1][x-1][i], st[1][x-1][st[0][x-1][i]]);
}
else{
st[0][x][i]=-1;
st[1][x][i]=oo;
}
}
build(x+1);
}
vector<int> up;
vector<vector<pair<int, int>>> graph;
vector<vector<int>> tree;
vector<int> level;
vector<pair<int, int>> edges;
vector<int> sp;
vector<bool> locked;
struct cmp{
bool operator()(pair<int, int> a, pair<int, int> b){
return a.f > b.f;
}
};
bool cmp2(pair<int, int> a, pair<int, int> b){
if(min(sp[a.f], sp[a.s]) == min(sp[b.f], sp[b.s]))return max(sp[a.f], sp[a.s]) > max(sp[b.f], sp[b.s]);
else return min(sp[a.f], sp[a.s]) < min(sp[a.f], sp[a.s]);
}
int Find(int x){
if(up[x] < 0)return x;
else{
up[x]=Find(up[x]);
return up[x];
}
}
void Union(int a, int b){
a = Find(a); b = Find(b);
up[b]=a;
}
void addedge(pair<int, int> x){
tree[x.f].push_back(x.s);
tree[x.s].push_back(x.f);
}
int travelup(int &x, int dist){
int re = oo;
if(dist == 0)return oo;
else{
for(int i = 0; i < mx2; i++){
if(dist&(1 << i)){
re = min(re, st[1][i][x]);
x = st[0][i][x];
}
}
}
return re;
}
void DFS(int x, int p){
for(auto u: tree[x]){
if(u == p)continue;
level[u]=level[x]+1;
st[0][0][u]=x;
st[1][0][u]=min(sp[x], sp[u]);
DFS(u, x);
}
}
int gtpath(int a, int b){
int ans = oo;
if(level[a] > level[b])swap(a, b);
ans = min(ans, travelup(b, level[b]-level[a]));
if(a == b)return ans;
for(int i = mx2-1; i >= 0; i--){
if(st[0][i][a] != st[0][i][b]){
ans = min(ans, st[1][i][a]);
a = st[0][i][a];
ans = min(ans, st[1][i][b]);
a = st[0][i][b];
}
}
return min(ans, sp[st[0][0][a]]);
}
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
sp.assign(n+1, oo);
graph.resize(n+1);
locked.assign(n+1, 0);
level.assign(n+1, 0);
up.assign(n+1, -1);
st[0][0][1]=-1;
for(int i = 0; i < m; i++){
int a, b, c;
cin >> a >> b >> c;
graph[a].push_back({b, c});
graph[b].push_back({a, c});
edges.push_back({a, b});
}
cin >> k;
for(int i = 0; i < k; i++){
int x;
cin >> x;
sp[x]=0;
pq.push({0, x});
}
while(!pq.empty()){
auto x = pq.top();
pq.pop();
if(locked[x.s])continue;
locked[x.s]=true;
for(auto u: graph[x.s]){
if(sp[u.f] > u.s+sp[x.s]){
sp[u.f] = u.s+sp[x.s];
pq.push({sp[u.f], u.f});
}
}
}
tree.resize(n+1);
sort(edges.begin(), edges.end(), cmp2);
//for(int i = 1; i <= n; i++)cout << sp[i] << " ";
//cout << endl;
for(int i = 0; i < m; i++){
if(Find(edges[i].f) != Find(edges[i].s)){
Union(edges[i].f, edges[i].s);
//cout << edges[i].f << " " << edges[i].s << endl;
addedge(edges[i]);
}
}
DFS(1, 0);
build(1);
cin >> q;
for(int i = 0; i < q; i++){
int a, b;
cin >> a >> b;
cout << gtpath(a, b) << "\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |