题意:有n个点,m条边,还有一个总上界k,你需要从s点走到t点,对于每条边u,v,l,r,你手中持有的权值需要在[l,r]的范围内才能从u走到v,问有多少种不同的权值可以成功地从s点走到t。
思路:一开始直接从[1,k]开始搜,到每个可行的区间就存下来,最后对合法区间求和,但是不行,可能回溯太耗时间?
将每一扇们门的上下界都存储起来,我们可以知道,最终合法的若干区间的端点值一定来自于这些点,那么我们每次只需要暴力判断端点值了可不可行,那么就u能知道这个区间可不可行了.
#include<bits/stdc++.h>
#define ll unsigned long long
using namespace std;
const int N = 1e4 + 10;
int n, m, k, s, t, h[N], cnt, ans, vis[N], a[N << 1], ifs;
struct node {
int v, c, d, nt;
} no[N];
void add(int u, int v, int c, int d) {
no[cnt] = node{v, c, d, h[u]};
h[u] = cnt++;
}
void dfs(int u, int fa, int l, int r) {
vis[u] = 1;
if(u == t) {
ifs = 1;
return;
}
for(int i = h[u]; ~i; i = no[i].nt) {
int v = no[i].v;
if(v != fa && !vis[v]) {
if(l >= no[i].c && r <= no[i].d)
dfs(v, u, l, r);
}
}
}
int main() {
memset(h, -1, sizeof h);
cin >> n >> m >> k >> s >> t;
int tot = 0;
for(int x, r, c, d, i = 1; i <= m; i++) {
scanf("%d%d%d%d", &x, &r, &c, &d);
add(x, r, c, d);
a[++tot] = c, a[++tot] = d;
}
sort(a + 1, a + tot + 1);
int mx = 0;
for(int i = 2; i <= tot; i++) {
memset(vis, 0, sizeof vis), ifs = 0;
dfs(s, 0, a[i - 1], a[i]);
if(ifs) {
ans += (a[i] - a[i - 1] + 1);
if(a[i - 1] == mx)
ans--;
mx = a[i];
}
}
cout << ans;
return 0;
}