Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) D题

本文探讨了一种复杂的导航系统工作原理,该系统在单向图中为从起点到终点的旅程选择并显示最短路径。重点介绍了系统如何在用户偏离推荐路径时重新计算最短路径,以及如何确定在特定路径上可能发生的最小和最大路径重建次数。

Navigation System

The map of Bertown can be represented as a set of n intersections, numbered from 1 to n and connected by m one-way roads. It is possible to move along the roads from any intersection to any other intersection. The length of some path from one intersection to another is the number of roads that one has to traverse along the path. The shortest path from one intersection v to another intersection u is the path that starts in v, ends in u and has the minimum length among all such paths.

Polycarp lives near the intersection s and works in a building near the intersection t. Every day he gets from s to t by car. Today he has chosen the following path to his workplace: p1, p2, …, pk, where p1=s, pk=t, and all other elements of this sequence are the intermediate intersections, listed in the order Polycarp arrived at them. Polycarp never arrived at the same intersection twice, so all elements of this sequence are pairwise distinct. Note that you know Polycarp’s path beforehand (it is fixed), and it is not necessarily one of the shortest paths from s to t.

Polycarp’s car has a complex navigation system installed in it. Let’s describe how it works. When Polycarp starts his journey at the intersection s, the system chooses some shortest path from s to t and shows it to Polycarp. Let’s denote the next intersection in the chosen path as v. If Polycarp chooses to drive along the road from s to v, then the navigator shows him the same shortest path (obviously, starting from v as soon as he arrives at this intersection). However, if Polycarp chooses to drive to another intersection w instead, the navigator rebuilds the path: as soon as Polycarp arrives at w, the navigation system chooses some shortest path from w to t and shows it to Polycarp. The same process continues until Polycarp arrives at t: if Polycarp moves along the road recommended by the system, it maintains the shortest path it has already built; but if Polycarp chooses some other path, the system rebuilds the path by the same rules.

Here is an example. Suppose the map of Bertown looks as follows, and Polycarp drives along the path [1,2,3,4] (s=1, t=4):

Check the picture by the link http://tk.codeforces.com/a.png

  1. When Polycarp starts at 1, the system chooses some shortest path from 1 to 4. There is only one such path, it is [1,5,4];
  2. Polycarp chooses to drive to 2, which is not along the path chosen by the system. When Polycarp arrives at 2, the navigator rebuilds the path by choosing some shortest path from 2 to 4, for example, [2,6,4] (note that it could choose [2,3,4]);
  3. Polycarp chooses to drive to 3, which is not along the path chosen by the system. When Polycarp arrives at 3, the navigator rebuilds the path by choosing the only shortest path from 3 to 4, which is [3,4];
  4. Polycarp arrives at 4 along the road chosen by the navigator, so the system does not have to rebuild anything.
    Overall, we get 2 rebuilds in this scenario. Note that if the system chose [2,3,4] instead of [2,6,4] during the second step, there would be only 1 rebuild (since Polycarp goes along the path, so the system maintains the path [3,4] during the third step).

The example shows us that the number of rebuilds can differ even if the map of Bertown and the path chosen by Polycarp stays the same. Given this information (the map and Polycarp’s path), can you determine the minimum and the maximum number of rebuilds that could have happened during the journey?

Input
The first line contains two integers n and m (2≤n≤m≤2⋅105) — the number of intersections and one-way roads in Bertown, respectively.

Then m lines follow, each describing a road. Each line contains two integers u and v (1≤u,v≤n, u≠v) denoting a road from intersection u to intersection v. All roads in Bertown are pairwise distinct, which means that each ordered pair (u,v) appears at most once in these m lines (but if there is a road (u,v), the road (v,u) can also appear).

The following line contains one integer k (2≤k≤n) — the number of intersections in Polycarp’s path from home to his workplace.

The last line contains k integers p1, p2, …, pk (1≤pi≤n, all these integers are pairwise distinct) — the intersections along Polycarp’s path in the order he arrived at them. p1 is the intersection where Polycarp lives (s=p1), and pk is the intersection where Polycarp’s workplace is situated (t=pk). It is guaranteed that for every i∈[1,k−1] the road from pi to pi+1 exists, so the path goes along the roads of Bertown.

Output
Print two integers: the minimum and the maximum number of rebuilds that could have happened during the journey.


题目比较长,题意大致为:给你一个单向图,然后固定k个点(设固定的点数组为a[]),依次都要从这些点出发,最终要到达a[k] ,求最大最小重建路的数量;

当你从a[1]出发时,a[1]到a[k]的最短路线如果包含下一个点a[2],那么就不要重建路了,如果不包含,那么必要重建一条路,又从a[2]开始走;

这道题的想法有点像最短路计算,当点a[1]到a[2]有多条最短边时,那么可以重建可以不重建,如果一条没有,那么必须重建;

所以首先要反向建图,找到各个点到a[k]的最短距离,并且找到每个点在最短路的路径数(也就是入度),就可以了;

代码:

#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
#define inf 0x3f3f3f3f
//ios::sync_with_stdio(false);
using namespace std;
const int N=200100;
const int M=1000100;
int n,m,k;
int a[N],head[N],cnt;
struct Node{
	int to,nex;
}edge[N];
void add(int p,int q){
	edge[cnt].to=q;
	edge[cnt].nex=head[p];
	head[p]=cnt++;
}
int dis[N],in[N];//最短路径和入度点数 
void bfs(int p){
	memset(dis,-1,sizeof(dis));
	dis[p]=0,in[p]=0;
	queue<int>qu;
	qu.push(p);
	while(!qu.empty()){
		int u=qu.front();
		qu.pop();
		for(int i=head[u];~i;i=edge[i].nex){
			int v=edge[i].to;
			if(dis[v]==-1) dis[v]=dis[u]+1,qu.push(v),in[v]=1;
			else if(dis[v]==dis[u]+1) in[v]=2;
		}
	}
}
int main(){
    ios::sync_with_stdio(false);
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    for(int i=1;i<=m;i++){
    	int p,q;
    	cin>>p>>q;
    	add(q,p);
	}
	cin>>k;
	for(int i=1;i<=k;i++) cin>>a[i];
	bfs(a[k]);
	int ans1=0,ans2=0;
	for(int i=1;i<k;i++){
		if(dis[a[i]]==dis[a[i+1]]+1){//表示在一条最短路上面 
			ans2+=in[a[i]]-1; 
		}
		else ans1++,ans2++;//不在一条路上面,必须重建 
	}
	cout<<ans1<<" "<<ans2<<endl; 
    return 0;
}
对于Codeforces Round 1005 Div. 2中的D解答或解释,当前提供的引用资料并未直接涉及该轮次的比赛目详情。然而,可以基于过往比赛的经验以及相似类型的编程竞赛问提供一般性的指导。 ### 解决方案概述 通常情况下,在解决此类算法竞赛目时,会遵循特定的方法论来处理输入数据并计算所需的结果。虽然具体到Codeforces Round 1005 Div. 2 Problem D的信息未被提及,但可以根据以往经验推测可能涉及到的数据结构和算法技术: - **读取测试案例数量**:程序首先应该能够接收多个独立的测试案例数目\(t\),其中每一个案例都包含了不同的参数集[^3]。 - **解析数组元素**:针对每个测试案例,需解析给定长度为\(n\)的一系列整数\[a_1, a_2,...,a_n\]作为操作对象[^2]。 - **查询次数限制**:需要注意的是,所有测试案例中查询总数不得超过设定的大值,比如这里提到不超过\(2 \times 10^5\)次查询[^1]。 - **输出格式规定**:当准备打印终答案时,应按照指定格式输出结果,并继续处理下一个测试案例直到完成全部测试[^4]。 考虑到这些通用原则,如果要设计一个适用于此类型问的解决方案框架,则可能会如下所示: ```python def solve_problem(): import sys input = sys.stdin.read data = input().split() index = 0 results = [] t = int(data[index]) index += 1 for _ in range(t): n = int(data[index]) index += 1 numbers = list(map(int, data[index:index+n])) index += n # 假设这里是解决问的核心逻辑部分, # 需要根据具体的Problem D描述调整这部分代码实现。 result_for_case = "Example Result" results.append(result_for_case) print("\n".join(results)) ``` 上述伪代码展示了如何构建基本架构用于批量处理多组测试用例,但是核心业务逻辑需要依据实际问定义进行填充和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值