Y
K
N
U
F

#HZTG6031. 图上游走

#HZTG6031. 图上游走

不错的思路,很快想到了,可惜场上少写了一个等于的情况(也就是少写六行)
\(100−>54\)

考虑 \(n\) 大小一般,显然要作为状态的其中之一,又考虑 \(l,r,w,x,y\) 都不大,将其也设计成状态,以此完成一个搜索,考虑每一个点可能的转移在第一次搜索到后就不会有新的花样,故搜索后直接记录,下次再遇到就直接退出,又考虑 \(n\) 其实也不太大,在边上的运动直接模拟也最多不过是一个 \(200\) 的常数,大抵不会 T,所以直接模拟,码一份复制四份(导致代码奇长)。每个点最多被搜索 \(200\) 次,每条边同理,边上运动最多 \(200\) 次,每次询问都是以 \(O(1)\) 时间回答。综上,总复杂度\(O(40000×m+200×n+q)\)

#include <bits/stdc++.h>
using namespace std;
const int N = 50000 + 100;
struct node {
	int v, l, w;
};
vector<node> e[N], g[N];//g反图 
int n, m, q, L, R;
bool can[N][250];
// 末位置 结束状态
inline void dfs(int u, int s) {             
	if(can[u][s+110]) return;
	can[u][s+110] = 1;
	int S = s;
	if(S > 0) {
		for(node v : e[u]) {
			s = S;
			if(v.w > S) {
				int t = 1; s ++;
				while(t != 0 and t != v.l) {
					if(s > 0) t ++;
					else if (s == 0);
					else t --;
					if(s != v.w) s += (s > v.w)? -1 : 1;
					else if(s == v.w and s == 0 and t != 0 and t != v.l) {
						t = -1;
						break;
					}
				}
				if(t == 0) dfs(u, s);
				else if (t == v.l) dfs(v.v, s);
			}
			else if(v.w < S) {
				int t = 1; s --;
				while(t != 0 and t != v.l) {
					if(s > 0) t ++;
					else if (s == 0);
					else t --;
					if(s != v.w) s += (s > v.w)? -1 : 1;
					else if(s == v.w and s == 0 and t != 0 and t != v.l) {
						t = -1;
						break;
					}
				}
				if(t == 0) dfs(u, s);
				else if (t == v.l) dfs(v.v, s);
			}
			else if(v.w == S) {
				dfs(v.v,s);
			}
		}
	}
	else if(S < 0) {
		for(node v : g[u]) {
			s = S;
			if(v.w > S) {
				int t = 1; s ++;
				while(t != 0 and t != v.l) {
					if(s > 0) t --;
					else if (s == 0);
					else t ++;
					if(s != v.w) s += (s > v.w)? -1 : 1;
					else if(s == v.w and s == 0 and t != 0 and t != v.l) {
						t = -1;
						break;
					}
				}
				if(t == 0) dfs(u, s);
				else if (t == v.l) dfs(v.v, s);
			}
			else if(v.w < S) {
				int t = 1; s --;
				while(t != 0 and t != v.l) {
					if(s > 0) t --;
					else if (s == 0);
					else t ++;
					if(s != v.w) s += (s > v.w)? -1 : 1;
					else if(s == v.w and s == 0 and t != 0 and t != v.l) {
						t = -1;
						break;
					}
				}
				if(t == 0) dfs(u, s);
				else if (t == v.l) dfs(v.v, s);
			}
			else if(v.w == S) {
				dfs(v.v,s);
			}
		}
	}
}  
signed main() {
	ios::sync_with_stdio(0);
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
    cin >> n >> m >> q >> L >> R;
    for(int i = 1, u, v, w, l; i <= m; i++) {
    	cin >> u >> v >> l >> w;
		e[u].push_back({v,l,w});
		g[v].push_back({u,l,w});
	}
	for(int i = L; i <= R; i++)	dfs(1,i);
	for(int i = 1, x, y; i <= q; i++) {
		cin>>x>>y;
		if(can[x][y+110]) puts("Yes");
		else puts("No");
	}
}
posted @ 2025-07-13 08:06  樓影沫瞬_17Hz  阅读(8)  评论(0)    收藏  举报