AcWing 362. 区间
这道题是求集合内的数的个数的最小值,所以要用最长路径,dist[i]数组表示的是从1~i取的数的个数,所以有三道限制(S[i] >= S[i - 1]、S[i] - S[i - 1] <= 1、S[b] - S[a - 1] <= c)
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10, M = N * 3;
int n, m;
int dist[N];
bool st[N];
int cnt[N];
int h[N], e[M], ne[M], w[M], idx;
int q[N];
void add(int a, int b, int c){
e[idx] = b;
ne[idx] = h[a];
w[idx] = c;
h[a] = idx ++ ;
}
void spfa(){
memset(dist, -0x3f, sizeof dist);
int hh = 0, tt = 1;
q[0] = 0;
st[0] = true;
dist[0] = 0;
while(hh != tt){
int t = q[hh ++ ];
if(hh == N) hh = 0;
st[t] = false;
for(int i = h[t]; ~i; i = ne[i]){
int j = e[i];
if(dist[j] < dist[t] + w[i]){
dist[j] = dist[t] + w[i];
if(!st[j]){
q[tt ++ ] = j;
if(tt == N) tt = 0;
st[j] = true;
}
}
}
}
}
int main()
{
cin>>n;
memset(h, -1, sizeof h);
for(int i = 1; i < N; i ++ ){
add(i - 1, i, 0); //限制中是1~i选的数的个数(S[i])>=1~i-1选的数的个数(S[i-1]) <=> S[i] >= S[i-1]
add(i, i - 1, -1); //限制中是S[i] - S[i-1] <= 1 <=> S[i] - 1 <= S[i-1]
}
for(int i = 0; i < n; i ++ ){
int a, b, c;
cin>>a>>b>>c;
a ++ ;
b ++ ;
add(a - 1, b, c); //注意题中要求的是包含区间端点a,参照前缀和思想,这里的左端要a-1
}
spfa();
cout<<dist[50001]<<endl;
return 0;
}