调不下去了
#include<bits/stdc++.h>
#define int long long
#define inf 2147483647
using namespace std;
struct node{
int to, w;
};
int size[100100];
vector<node> vec[100100];
int depth[100100];
int fa[100100];
int fat[100100];
int tree[100100<<3];
int n, m, k, q;
int s[100100];
int dfn[100100];
int new_w[100100];
struct node2{
int from, to, w, is;
}edge[300100];
bool cmp(node2 x, node2 y) {
return x.w < y.w;
}
int son[100100];
int top[100100], wson[100100];
vector<node> new_vec[100100];
void dfs1(int index, int fa=0) {
size[index] = 1;
for(int i=0; i<new_vec[index].size(); ++i) {
if(fa == new_vec[index][i].to) continue;
dfs1(new_vec[index][i].to, index);
size[index] += size[new_vec[index][i].to];
if(size[new_vec[index][i].to] > size[s[index]]) {
s[index] = new_vec[index][i].to;
wson[index] = new_vec[index][i].w;
}
}
}
int df = 0;
void dfs2(int index, int fa=0, int tp = 0) {
dfn[index] = ++df;
top[index] = tp;
fat[index] = fa;
depth[index] = depth[fa] + 1;
if(son[index] != 0) {
dfs2(son[index], index, tp);
new_w[dfn[son[index]]] = wson[index];
}
for(int i=0; i<new_vec[index].size(); ++i) {
if(new_vec[index][i].to == son[index] || new_vec[index][i].to == fa) {
continue;
}
dfs2(new_vec[index][i].to, index, new_vec[index][i].to);
new_w[dfn[new_vec[index][i].to]] = new_vec[index][i].w;
}
}
void build(int index, int l, int r) {
if(l == r) {
tree[index] = new_w[index];
return;
}
int mid = l + r >> 1;
build(index*2, l, mid); build(index*2+1, mid+1, r);
tree[index] = max(tree[index*2], tree[index*2+1]);
}
int find(int index) {
if(fa[index] == index) {
return index;
}
return fa[index] = find(fa[index]);
}
int dis[100100], vis[100100];
void dijkstra(int s) {
memset(dis, 0x3f, sizeof dis);
dis[s] = 0;
priority_queue<pair<int,int> > que;
que.push({0, s});
while(!que.empty()) {
int t = que.top().second; que.pop();
if(vis[t]) continue;
vis[t] = 1;
for(int i=0; i<vec[t].size(); ++i) {
int to = vec[t][i].to;
if(dis[to] > dis[t] + vec[t][i].w) {
dis[to] = dis[t] + vec[t][i].w;
que.push({-dis[to], to});
}
}
}
}
int ask1(int index, int l, int r, int left, int right) {
if(l > right || r < left) return -1;
if(l >= left && r <= right) {
return tree[index];
}
int mid = l + r >> 1;
return max(ask1(index*2, l, mid, left, right), ask1(index*2+1, mid+1, r, left, right));
}
int ask(int index1, int index2) {
int maxx = -1;
while(top[index1] != top[index2]) {
if(depth[top[index1]] > depth[top[index2]]) {
swap(index1, index2);
}
maxx = max(maxx, ask1(1, 1, n, dfn[top[index2]], dfn[index2]));
index2 = fat[top[index2]];
}
if(depth[index1] > depth[index2]) {
swap(index1, index2);
}
maxx = max(maxx, ask1(1, 1, n, dfn[index2]+1, dfn[index1]));
return maxx;
}
signed main() {
cin >> n >> m >> k >> q;
for(int i=1; i<=m; ++i) {
int from, to, w; cin >> from >> to >> w;
edge[i].from = from; edge[i].to = to; edge[i].w;
vec[from].push_back({to, w}); vec[to].push_back({from, w});
}
for(int i=1; i<=k; ++i) {
vec[n+1].push_back({i, 0});
}
dijkstra(n+1);
for(int i=1; i<=m; ++i) {
edge[i].w = dis[edge[i].from] + dis[edge[i].to] + edge[i].w;
}
for(int i=1; i<=n; ++i) {
fa[i] = i;
}
sort(edge+1, edge+1+m, cmp);
for(int i=1; i<=m; ++i) {
if(find(edge[i].from) == find(edge[i].to)) {
continue;
}
int x = find(edge[i].from), y = find(edge[i].to);
x = fa[y]; edge[i].is = 1;
}
for(int i=1; i<=m; ++i) {
if(edge[i].is) {
new_vec[edge[i].from].push_back({edge[i].to, edge[i].w});
}
}
dfs1(1, 0);
dfs2(1, 0);
build(1, n, 1);
while(q--) {
int x1, x2; cin >> x1 >> x2;
cout << ask(x1, x2) << endl;
}
return 0;
}