分析
那么这道题可以转换成差分约束系统,首先要换成前缀和,对于 [ a ∼ b ] [a\sim b] [a∼b]必须不少于 w w w也就是 s [ b ] − s [ a − 1 ] ≥ w s[b]-s[a-1]\geq w s[b]−s[a−1]≥w,然后还有限制就是两个相邻的数的前缀和的差要么为0,要么为1,所以 0 ≤ s [ k ] − s [ k − 1 ] ≤ 1 0\leq s[k]-s[k-1]\leq 1 0≤s[k]−s[k−1]≤1,建立一个最长路,然后正环是不可能的,因为题目说了 w ≤ b − a + 1 w\leq b-a+1 w≤b−a+1,所以只需要老老实实跑最长路,最后输出 d i s [ 50000 ] dis[50000] dis[50000],但是由于存在 0 和 − 1 0和-1 0和−1所以集体+2
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <queue>
#define rr register
using namespace std;
struct node{int y,w,next;}e[150101];
int ls[50101],dis[50101],k=1; bool v[50101];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
signed main(){
for (rr int i=iut();i;--i){
rr int x=iut()+1,y=iut()+2,w=iut();
e[++k]=(node){y,w,ls[x]}; ls[x]=k;
}
for (rr int i=1;i<50002;++i){
e[++k]=(node){i+1,0,ls[i]}; ls[i]=k;
e[++k]=(node){i,-1,ls[i+1]};ls[i+1]=k;
}
memset(dis,0xcf,sizeof(dis));
rr queue<int>q;
q.push(1); v[1]=1; dis[1]=0;
while (q.size()){
rr int x=q.front(); q.pop();
for (rr int i=ls[x];i;i=e[i].next)
if (dis[e[i].y]<dis[x]+e[i].w){
dis[e[i].y]=dis[x]+e[i].w;
if (!v[e[i].y]) v[e[i].y]=1,q.push(e[i].y);
}
v[x]=0;
}
return !printf("%d\n",dis[50002]);
}