이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define ar array< int , 2>
#define MASK(i) (1 << (i))
#define BIT(x, i) (((x) >> (i)) & 1)
template<typename T1, typename T2> bool minN(T1 &a, T2 b) {if (a > b) a = b; else return 0; return 1;}
template<typename T1, typename T2> bool maxX(T1 &a, T2 b) {if (a < b) a = b; else return 0; return 1;}
const int MAX = 1e6 + 1000, INFL = 1e9 + 7, LOG = 18;
int  n, m, x, y, z, k, f[LOG + 1][MAX], minDanger[LOG + 1][MAX], high[MAX], q;
bool NSS[MAX], par[MAX];
ar d[MAX], dd[MAX];
vector < ar > A[MAX];
vector < int > B[MAX];
struct DSU
{
    vector < long long > ff;
    void Init(long long _n) {ff.resize(_n + 100, -1);}
    long long Root(long long x) {return (ff[x] <= -1 ? x : ff[x] = Root(ff[x]));}
    bool Join(long long x, long long y)
    {
        x = Root(x); y = Root(y);
        if (x == y) return false;
        if (ff[x] > ff[y]) swap(x, y);
        ff[x] += ff[y]; ff[y] = x;
        return true;
    }
    bool Check(long long x, long long y) {return Root(x) == Root(y);}
};
DSU dsu;
void BFS()
{
    queue< ar > QU;
    for (int i = 1; i <= n; i++) if (NSS[i]) QU.push({0, i}), d[i][0] = 0;
    while (!QU.empty())
    {
        ar x = QU.front();
        QU.pop();
        //if (d[x[1]][0] != x[0]) continue;
        for (ar y : A[x[1]])
        {
            if (d[y[0]][0] > x[0] + y[1])
            {
                d[y[0]][0] = x[0] + y[1];
                QU.push({d[y[0]][0], y[0]});
            }
        }
    }
}
bool Compare(ar x, ar y)
{
    return d[x[0]] > d[y[0]];
}
void MakeTree()
{
    for (int i = 1; i <= n; i++)
    {
        dd[i] = d[i];
    }
    sort(dd + 1, dd + 1 + n, greater< ar >());
    for (int i = 1; i <= n; i++)
    {
        ar x = dd[i];
        par[x[1]] = 1;
        sort(A[x[1]].begin(), A[x[1]].end(), Compare);
        for (ar y : A[x[1]])
        {
            if (par[y[0]] && dsu.Join(x[1], y[0]))
            {
                B[x[1]].push_back(y[0]);
                B[y[0]].push_back(x[1]);
            }
        }
    }
}
void DFS(int x, int p)
{
    for (int y : B[x])
    {
        if (p != y)
        {
            f[0][y] = x;
            minDanger[0][y] = min(d[y][0], d[x][0]);
            cout << y << " " << minDanger[0][y] << '\n' ;
            high[y] = high[x] + 1;
            DFS(y, x);
        }
    }
}
void Prepare()
{
    high[0] = -1;
    DFS(1, 0);
    for (int k = 1; k <= LOG; k++)
    {
        for (int x = 1; x <= n; x++)
        {
        f[k][x] = f[k - 1][f[k - 1][x]];
        minDanger[k][x] = min(minDanger[k - 1][x], minDanger[k - 1][f[k - 1][x]]);
        }
    }
}
int LCA(int x, int y)
{
    if (high[x] < high[y]) return LCA(y, x);
    int ans = INFL;
    for (int k = LOG; k >= 0; k--)
    {
        if (high[f[k][x]] >= high[y])
            minN(ans, minDanger[k][x]), x = f[k][x];
    }
    //cout << ans << '\n' ;
    if (x == y) return ans;
    for (int k = LOG; k >= 0; k--)
    {
        if (f[k][x] != f[k][y])
        {
            minN(ans, minDanger[k][x]);
            minN(ans, minDanger[k][y]);
            x = f[k][x];
            y = f[k][y];
        }
    }
    while (x != y)
    {
        minN(ans, minDanger[0][x]);
        minN(ans, minDanger[0][y]);
        x = f[0][x];
        y = f[0][y];
    }
    return ans;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    memset(minDanger, 0x3f, sizeof minDanger);
    memset(d, 0x3f, sizeof d);
    cin >> n >> m;
    dsu.Init(n);
    for (int i = 1; i <= m; i++)
    {
        cin >> x >> y >> z;
        A[x].push_back({y, z});
        A[y].push_back({x, z});
    }
    cin >> k;
    for (int i = 1; i <= k; i++)
    {
        cin >> x;
        NSS[x] = 1;
    }
    for (int i = 1; i <= n; i++) d[i][1] = i;
    BFS();
    MakeTree();
    Prepare();
    //for (int i = 1; i <= n; i++) for (int j : B[i]) if (i < j) cout << i << " " << j << '\n' ;
    //cout << '\n' ;
    //for (int i = 1 ;i <= n; i++) cout << d[i][0] << " " << d[i][1] << '\n' ;
    cin >> q;
    for (int i = 1; i <= q; i++)
    {
        cin >> x >> y;
        //cout << minDanger[0][x] << " " << minDanger[0][y] << '\n' ;
        cout << LCA(x, y) << '\n' ;
    }
}
/*
9 12
1 9 4
1 2 5
2 3 7
2 4 3
4 3 6
3 6 4
8 7 10
6 7 5
5 8 1
9 5 7
5 4 12
6 8 2
2
4 7
5
1 6
5 3
4 8
5 8
1 5
*/
| # | 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... |