제출 #1333323

#제출 시각아이디문제언어결과실행 시간메모리
1333323maomaoEvacuation plan (IZhO18_plan)C++20
100 / 100
737 ms83016 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,s,n) for(int i=s;i<=n;i++)
#define vi vector<int>
#define pb push_back
#define pii pair<int,int>
#define eb emplace_back
#define fi first
#define se second
#define tup array<int, 3>
const int N = 1e5 + 5, L = 20;
vector<vector<pii>> adj(N), g(N);
int a,b,w;
vi pa(N), dep(N), dist(N, LLONG_MAX);
int par[20][N], mn[20][N];

int fpar(int u) {
	if(pa[u] == u) return pa[u];
	return pa[u] = fpar(pa[u]);
}


int qry(int u, int v) {
	int res = min(dist[u], dist[v]);
	if(dep[u] > dep[v]) swap(u, v);
	int dif = dep[v] - dep[u];
	for(int i=19;i>=0;i--) if(dif>>i & 1) {
		res = min(res,mn[i][v]);
		v=par[i][v];
	}
	if(u==v) return res;
	for(int i=19;i>=0;i--) {
		if(par[i][u] != par[i][v]) {
			res = min({res,mn[i][u],mn[i][v]});
			u = par[i][u];
			v = par[i][v];
		}
	}
	return min({res, mn[0][u], mn[0][v]});
}

void dfs(int u, int pp) {
	par[0][u] = pp;
	mn[0][u] = min(dist[u], (pp==-1?LLONG_MAX:dist[pp]));
	for(pii p : g[u]) {
		if(p.fi==pp) continue;
		dep[p.fi] = dep[u] + 1;
		dfs(p.fi, u);
	}
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    rep(i,1,n) pa[i] = i;
    vector<tup> ed;
    rep(i,1,m) {
		cin>>a>>b>>w;
		ed.pb({w,a,b});
		adj[a].eb(b,w);
		adj[b].eb(a,w);
	}
	
	priority_queue<pii, vector<pii>, greater<pii>> pq;
	int k; cin>>k;
	rep(i,1,k) {
		cin>>a;
		dist[a]=0;
		pq.push({0,a});
	}
	

	//compute min dist from x to all special cities
	while(!pq.empty()) {
		w = pq.top().fi;
		a = pq.top().se;
		pq.pop();
		for(pii p1 : adj[a]) {
			if(dist[p1.fi]>w+p1.se) {
				dist[p1.fi] = w+p1.se;
				pq.push({dist[p1.fi], p1.fi});
			}
		}
	}
	
	//maximum spanning tree
	for(tup &t:ed) t[0] = min(dist[t[1]], dist[t[2]]);
	sort(ed.begin(), ed.end(), greater<tup>());
	
	for(tup t : ed) {
		a=t[1]; b=t[2]; w=t[0];
		if(fpar(a) != fpar(b)) {
			g[a].eb(b,w);
			g[b].eb(a,w);
			pa[fpar(a)] = fpar(b);
		}
	}

	//dfs tree rooted at 1
	dep[1] = 1;
	dfs(1, 0);

	rep(i,1,19) rep(j,1,n) {
		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;
	while(q--) {
		cin>>a>>b;
		cout << qry(a,b) << "\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...