首页 > 其他分享 >Luogu P5663 CSP-J2019 加工零件 题解 [ 绿 ] [ 同余最短路 ]

Luogu P5663 CSP-J2019 加工零件 题解 [ 绿 ] [ 同余最短路 ]

时间:2024-09-29 23:44:30浏览次数:8  
标签:P5663 int 题解 路径 Luogu 长度 ns 2k dis

加工零件:非常好的一道图论题。CCF 普及组的题目大概也只有图论出的比较巧妙了。

题意简述:给你一张无向图,\(q\) 次询问,判断是否存在一条从 \(a\) 到 \(1\) 且长度为 \(L\) 的路径。

看到 \(L\) 很大,我们立刻想到了要撇开 \(L\) 的限制思考问题。

首先,对于一条路径,我们肯定能找到从 \(1\) 到 \(v\) 的一条最短路径,它的长度为 \(s\)。

此时我们可以发现,这时候我们一定可以找到长度为 \(s,s+2,s+4,...,s+2k\) 的路径。

为什么?因为这张图是无向图,我们可以沿着一条边走,来回一趟,这样我们的时间就会增加 \(2\) 了。

那么假设我们要 \(s+1,s+3,...,s+2k+1\) 的长度怎么办?我们只需要找到一个长度为 \(s+2k+1\) 的最短路径即可,这样长度为 \(s+2k+1+2j\) 的路径就都能找到。

这就启发我们把一个点分为此时时间为奇数和此时时间为偶数两种了。

我们可以把点翻倍,然后 BFS 的过程中记录此时是奇数路径还是偶数路径,进入到相应状态的点中,每个点的每个状态最多只会走到一次,这样就能在 \(O(n)\) 内求解了。这便是同于最短路的一个简单应用。

那么每次询问怎么处理?显然,当 \(L\) 为奇数时,判断它是否大于等于奇数状态的这个点的最短路长度。若是,则说明可以,否则说明到不了。因为他们是同余的。偶数同理。

写代码的时候把 bitset 两维弄反了,喜提 RE,竟然还把样例过掉了,离谱 CCF。

注意 bitset 尖括号里的那一维是最后一维!!!进食厚仁!!!

代码:

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
int n,m,t,dis[1000005][2];
vector<int>g[1000005];
struct node{
	int u,s,d;
};
queue<node>q;
bitset<2>vis[1000005];
void init()
{
	memset(dis,0x3f,sizeof(dis));
	dis[1][0]=0;
	vis[1][0]=1;
	q.push({1,0,0});
	while(!q.empty())
	{
		node tmp=q.front();
		int u=tmp.u,s=tmp.s,d=tmp.d,ns=(s+1)%2;
		q.pop();
		for(auto v:g[u])
		{
			if(vis[v][ns]==0)
			{
				vis[v][ns]=1;
				dis[v][ns]=d+1;
				q.push({v,ns,d+1});
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>t;
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	init();
	while(t--)
	{
		int a,l;
		cin>>a>>l;
		if(l%2==1)
		{
			if(dis[a][1]<=l)cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
		}
		else
		{
			if(dis[a][0]<=l)cout<<"Yes"<<endl;
			else cout<<"No"<<endl;			
		}
	}
	return 0;
}

标签:P5663,int,题解,路径,Luogu,长度,ns,2k,dis
From: https://www.cnblogs.com/zhr0102/p/18440979

相关文章

  • Hetao P2071 打字游戏 题解 [ 绿 ] [ 最小生成树 ] [ 动态规划 ] [ 编辑距离 ]
    打字游戏:MST套dp好题。首先看这个数据范围,\(O(n^4)\)把每两个字符串之前的编辑距离求一下很显然吧。然后我们观察一下每一个node的性质,发现他要么自己打完,要么从别人那里复制过来。这个就很像一棵树。建完树之后,我们就得到了一个森林。那么题目就转化为,求出一个边权之和......
  • Windows 笔记本 WiFi 功能消失问题解决
    背景说明许多Windows笔记本用户可能会遇到WiFi功能突然消失的问题。虽然网上有各种说法,但实际上,这个问题通常并非由病毒引起。大多数情况下,问题的根源是驱动程序丢失或笔记本静电干扰导致无线网卡无法正常工作。临时联网在解决WiFi问题期间,需要联网,可以尝试以下方法:使......
  • 题解:P11132 【MX-X5-T4】「GFOI Round 1」epitaxy
    1.做法及证明因为\(n\)一定会被包含在某一区间内,所以最后答案肯定是\(n\)的因数。先给出结论:对于\(n\)的因数\(d\),其合法的充要条件为\(d\lem\),所以我们只需要找到第一个小于等于\(m\)的\(d\)即可。接下来我们来证明。下文用\(i'\)表示以第\(i\)位开头的长度......
  • NEERC2014题解
    A结论题,行着取intn,m;signedmain(void){#ifdefONLINE_JUDGEfreopen("alter.in","r",stdin);freopen("alter.out","w",stdout);#endif read(n),read(m); writeln(n/2+m/2); for(inti=2;i<=n;i......
  • [USACO23JAN] Tractor Paths P 题解
    T4[USACO23JAN]TractorPathsP唯二的两道蓝题之一,但难度至少紫黑之间。思路是这篇题解的。首先一个贪心:跳到与当前区间相连的最靠右的区间肯定是最优的,由此倍增易得第一问。重点在于第二问的求解,我们发现这个东西很麻烦,这时候就需要一些寄巧了。具体来说,前人之述备矣。坑点:D......
  • 题解:AtCoder Beginner Contest AT_abc373_d ABC373D Hidden Weights
    题目传送门题目翻译给你一个NNN个点,MMM条边的有向图,其中边有边......
  • [2023四校联考3]sakuya 题解(根号分治)
    题目链接。题目分析第一个操作类似哈希冲突那一道题,可以运用类似的思路开一个二维表,很容易想到两种做法:开一个二维表,表上的第\(i\)行,第\(j\)列表示序列下标在模\(i\)意义下等于\(j\)的加法标记。对于修改操作,直接暴力修改对应的那一行的值即可,查询时用线段树查询那个......
  • 联考题解
    联考题解龙(dragon)难点:(1)删边后如何寻找新的最短路。(2)A,B两方的决策互相影响十分复杂。(3)如何统计每个起点的ans。解题:(3)解决这类多起点一终点的问题,可以想到dp。(1)解决这类最短路转移的问题,可以考虑最短路树。(2)解决这类博弈问题,可以设计两个dp数组,分别维护影响前后的ans,在转移......
  • [雅礼集训 2017 Day1]市场 题解
    题目链接题目分析听说是很典的一道题,很明显难点在于除法下取整的操作。类似花神那一道题,但是由于有区间加,所以无法进行暴力修改。很明显暴力复杂度爆炸,考虑下取整带来的性质:对于一对相邻的数,很明显有\(\lfloor\frac{x-1}{k}\rfloor\le\lfloor\frac{x}{k}\rfloor-1\)。......
  • i++和++i的区别,面试题解析
    i++和++i都是自增操作符,用于将变量的值增加1。i++是后增操作符,它首先返回变量的值,然后再将变量的值增加1。例如,如果i的初始值为1,执行i++后,i的值变为2。++i是前增操作符,它首先将变量的值增加1,然后再返回变量的值。例如,如果i的初始值为1,执行++i后,i的值变为2。区别在于返回值的......