#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");
}
}