AcWing 3797. 最大化最短路(排序优化枚举)

3797. 最大化最短路

题意

给定一个无向图,所有边权都为1,给定 \(k\) 个特殊点。

现要在这 \(k\) 个特殊点中选定两个连一条权值为1边,求连边后从 \(1\)\(N\) 的最短路最大值是多少。

思路

正反跑一次bfs,可以发现在特殊点 \(i,j\) 之间加一条边后会产生一条长度为 \(min(dis1[i] + disn[j] + 1\) , \(dis1[j] + disn[i] + 1)\) 的新路径。

最暴力的想法就是枚举这两个点,显然时间复杂度无法接受,现在关键在如何优化枚举过程。

对 $$min(dis1[i] + disn[j] + 1 , dis1[j] + disn[i] + 1)$$

我们假设先到 \(i\) 再到 \(j\) 更优,上式变形为 $$ dis1[i] - disn[i] < dis1[j] - disn[j] $$

也就是说,对任意的 \(i,j\) 满足上式就说明了先经过 \(i\) 再经过 \(j\) 更优,而这个式子左右两边的变量只有一个,就很方便进行排序。

我们将特殊点按上式排序后,可发现对于特殊点 \(i\) 的任意前缀 \(j\) ,一定是先过 \(i\) 再过 \(j\) 更优,那么只要维护这个前缀 max,就可以找到先经过任意特殊点 \(i\) 的新加入路径的最大值。

最后将原来最短路和处理出来的全局 \(max\) 就是答案。


#include<bits/stdc++.h>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define lowbit(x) x&-x
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int MAXN =10 + 2e5 ,mod=1e9 + 7;

void solve()
{    
    int N,M,K; cin >> N >> M >> K;
    vector<int> p(K + 1);
    for(int i = 1;i <= K;i ++) cin >> p[i];
    vector<vector<int>> adj(N + 1);
    for(int i = 0;i < M;i ++) {
        int u,v; cin >> u >> v;
        adj[u].push_back(v), adj[v].push_back(u);
    }
    auto bfs = [&](int s) {
        vector<int> dis(N + 1,-1);
        dis[s] = 0;
        queue<int> q; q.push(s);
        while(q.size()) {
            int u = q.front(); q.pop();
            for(auto v : adj[u]) if(dis[v] == -1) {
                dis[v] = dis[u] + 1;
                q.push(v);
            }
        }
        return dis;
    };
    auto dis1 = bfs(1);
    auto disn = bfs(N);

    sort(p.begin() + 1,p.end(),[&](int x,int y) {
        return dis1[x] - disn[x] > dis1[y] - disn[y];
    });
    int ans = 0;
    for(int i = 2,mx = disn[p[1]];i <= K;i ++) ans = max(ans,dis1[p[i]] + mx + 1), mx = max(mx,disn[p[i]]);
    cout << min(dis1[N],ans) << endl; 
}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);

    //int T;cin>>T;
    //while(T--)
        solve();

    return 0;
}
posted @ 2022-04-29 11:04  Mxrurush  阅读(17)  评论(0编辑  收藏  举报