CodeForces - 1307D Cow and Fields 差值排序

19 篇文章 0 订阅

一、内容

Bessie is out grazing on the farm, which consists of n fields connected by m bidirectional roads. She is currently at field 1, and will return to her home at field nat the end of the day.The Cowfederation of Barns has ordered Farmer John to install one extra bidirectional road. The farm has kspecial fields and he has decided to install the road between two different special fields. He may add the road between two special fields that already had a road directly connecting them.After the road is added, Bessie will return home on the shortest path from field 1to field n . Since Bessie needs more exercise, Farmer John must maximize the length of this shortest path. Help him!

Input

The first line contains integers n, m, and k (2≤n≤2⋅105, n−1≤m≤2⋅105, 2≤k≤n)  — the number of fields on the farm, the number of roads, and the number of special fields.The second line contains kintegers a1,a2,…,ak (1≤ai≤n)  — the special fields. All aiare distinct.The i-th of the following m lines contains integers xi and yi (1≤xi,yi≤n, xi≠yi), representing a bidirectional road between fields xi and yi It is guaranteed that one can reach any field from every other field. It is also guaranteed that for any pair of fields there is at most one road connecting them.

Output

Output one integer, the maximum possible length of the shortest path from field 1to nafter Farmer John installs one road optimally.

Input

5 5 3
1 3 5
1 2
2 3
3 4
3 5
2 4

Output

3

二、思路

在这里插入图片描述

三、代码

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int N = 2e5 + 5, M = N * 2;
struct E {int v, next;} e[M];
int n, m, k, u, v, p[N], len, h[N], d1[N], d2[N];
void add(int u, int v) {e[++len].v = v; e[len].next = h[u]; h[u] = len;}
void bfs(int d[], int u) {
	queue<int> q; q.push(u);
	memset(d, -1, sizeof(d1)); d[u] = 0;
	while (!q.empty()) {
		u = q.front(); q.pop();
		for (int j = h[u]; j; j = e[j].next) {
			int v = e[j].v;
			if (d[v] == -1) d[v] = d[u] + 1, q.push(v);
		}
	}
}
//按照 d1[u] - d2[u]从小到大排序 这样排序后的点(d1[u] - d2[u]) < (d1[v] - d2[v])
bool cmp(int u, int v) {return (d1[u] - d2[u]) < (d1[v] - d2[v]);} 
int main() {
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 1; i <= k; i++) scanf("%d", &p[i]);
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &u, &v); add(u, v); add(v, u);
	} 
	bfs(d1, 1);//1到其他点的最短路 
	bfs(d2, n);//n到其他点的最短路 
	sort(p + 1, p + 1 + k, cmp);
	int ans = 0, mx = -1e9; //由于第一个之前没有点 所以mx为负无穷 
	for (int i = 1; i <= k; i++) {
		v = p[i];
		//从前往后遍历 这样保证 (d1[u] - d2[u]) < (d1[v] - d2[v])
		//那么我们只需要加上1~v-1之前最大的d1 mx即可。
		ans = max(ans, mx + d2[v]); 
		mx = max(mx, d1[v]);
	}
	printf("%d", min(ans + 1, d1[n]));
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值