Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) D. Navigation System(最短路spfa+思维)

题目链接
在这里插入图片描述
在这里插入图片描述
题意:真是个恶心的题目,又臭又长,比赛的时候看的都快吐了。
其实就是给定一个有向图,和一个初始路径,你从初始路径一直走,当走到i时发现i到终点的最短路径和给出的初始路径不一样,系统就会重建,求重建的最小和最大次数。
思路:这题感觉完全在考你英文水平,知道题意后秒解,由于是有向图,所以需要反向建边,spfa求出n到各个点的最短路,假设当前点为x,对应初始路径是a【i】,显然如果d【x】和d【a【i】】相等并且x不等于a【i】的时候,最大次数+1,如果d【x】<d【a【i】】的时候系统肯定是要重建的无法避免的,最大和最小次数都要+1。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
const int maxn=2e5+1;
const int inf=0x3f3f3f3f;
int n,m,k,d[maxn],a[maxn],ans1,ans2;
bool vis[maxn]; 
vector<int>g1[maxn],g2[maxn];
void spfa(int x)
{
	memset(vis,false,sizeof(vis));
	for(int i=0;i<maxn;++i) d[i]=inf;
	d[x]=0;
	queue<int>q;
	q.push(x);
	vis[x]=true;
	while(!q.empty())
	{
		int top=q.front();
		q.pop();
		vis[top]=false;
		for(auto v:g2[top])
		{
			if(d[top]+1<d[v])
			{
				d[v]=d[top]+1;
				if(!vis[v]) q.push(v),vis[v]=true;
			}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;++i)
	{
		scanf("%d%d",&u,&v);
		g1[u].push_back(v);
		g2[v].push_back(u);
	}
	scanf("%d",&k);
	for(int i=1;i<=k;++i) scanf("%d",&a[i]);
	spfa(a[k]);
	for(int i=1;i<k;++i)
	{
		int flag1=0,flag2=0;
		for(int v:g1[a[i]])
		{
			if(v==a[i+1]) continue;
			if(d[v]==d[a[i+1]]) flag1=1;
			else if(d[v]<d[a[i+1]]) flag2=1;
		}
		if(flag2) ans1++,ans2++;
		else if(flag1) ans2++;
	}
	printf("%d %d\n",ans1,ans2);
}
发布了171 篇原创文章 · 获赞 0 · 访问量 5795

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104621471