最大化最短路

题目链接
题解:假设我们连接了两个点a,b,那么这条路是从1到a的距离+a到b的距离+b到n的距离。那么我们首先就要预处理出来两个距离,分别是1到各个点的最短距离为d1,另一个就是n到各个点的最短距离d2。我们再有了这个之后,就可以得到距离为min(d1[a]+1+d2[b],d1[b]+1+d2[a]),但是我们有了它以后如果暴力遍历所有点的话,是O(n²),很明显是会超时的。
我们可以把这两个式子中的元素交换交换下,会得到这样的一个式子,d1[a]-d1[b],d2[a]-d2[b],而我们要找的是两个当中比较小的,所以我们按照这个来进行排序。然后再遍历即可得到答案。

#include<bits/stdc++.h>
#define ll long long
#define pr pair<int,int>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
#define endl "\n"

using namespace std;
const int N = 2e5 + 5;
int d1[N], d2[N], a[N];
bool f[N];
struct node
{
	int to, next, w;
} e[N * 2];
int head[N], cnt = 0;
void add(int u,int v,int w)
{
	e[++cnt] = {v, head[u], w};
	head[u] = cnt;
}
void bfs(int a,int d[])
{
	memset(d, 0x3f, N*4);
	memset(f, 0, sizeof f);
	queue<int> q;
	q.push(a);
	d[a] = 0;
	f[a] = 1;
	while(q.size())
	{
		int b = q.front();
		q.pop();
		f[b] = 0;
		
		for (int i = head[b]; i;i=e[i].next)
		{
			int v = e[i].to, w = e[i].w;
			if(d[v]>d[b]+w)
			{
				d[v] = d[b] + w;
				if(f[v]==0)
					q.push(v), f[v] = 1;
			}
		}
	}
}
bool cmp(int a,int b)
{
	return d1[a] - d2[a] < d1[b] - d2[b];
}
int main()
{
	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 1; i <= k;i++)
	{
		cin >> a[i];
	}
	for (int i = 1; i <= m;i++)
	{
		int u, v, w;
		cin >> u >> v ;
		add(u, v, 1);
		add(v, u, 1);
	}
	bfs(1, d1);
	bfs(n, d2);
	sort(a + 1, a + 1 + k, cmp);
	int ans = 0, x = d1[a[1]];
	for (int i = 2; i <= k;i++)
	{
		int b = a[i];
		ans = max(ans, d2[b] + x + 1);
		x = max(x, d1[b]);
	}
	cout << min(d1[n],ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值