对于本题,最短路,考虑bfs,那么我们可以跑2次bfs,求出每个点到1与n的最短路,设为x_a, x_b,那我们可以把问题转换成max(min{x_a+y_b,x_b+y_a}+1)(x,y属于1到n),我们假设x_a+y_b<=x_b+y_a,那我们就是求出x_a+y_b的最大值,不等式转换一下,x_a-x_b<=y_a-y_b,那我们可以根据该式sort一下,每次更新一下最大的x_a,然后x_a+y_b+1就是最大值

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;

const int maxn = 2e5+5;

vector<int> G[maxn];
int d1[maxn], d2[maxn];
bool ks[maxn];

void bfs(int *dist, int s) {
    dist[s] = 0;
    queue<int> q;
    q.push(s);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(auto v : G[u]) {
            if(dist[v] == -1) {
                q.push(v);
                dist[v] = dist[u] + 1;
            }
        }
    }
}

void run_case() {
    int n, m, k;
    cin >> n >> m >> k;
    memset(d1, -1, sizeof(d1)), memset(d2, -1, sizeof(d2));
    for(int i = 0; i < k; ++i) {
        int t; cin >> t;
        ks[t] = true;
    }
    for(int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    bfs(d1, 1);
    bfs(d2, n);
    vector<pii> v;
    for(int i = 1; i <= n; ++i) if(ks[i]) v.emplace_back(d1[i], d2[i]);
    sort(v.begin(), v.end(), [&](const pii &a, const pii &b) {
        return a.first - a.second < b.first - b.second;
    });
    int ans = 0, mx = v[0].first;
    for(int i = 1; i < v.size(); ++i) {
        ans = max(ans, mx+1+v[i].second);
        mx = max(mx, v[i].first);
    }
    cout << min(ans, d1[n]);
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    //cout.setf(ios_base::showpoint);cout.precision(10);
    //int t; cin >> t;
    //while(t--)
    run_case();
    cout.flush();
    return 0;
}
View Code
02-14 03:00