大意:
第一行输入n,下面输入n个限制条件,条件的格式为 ai bi ci, 0<=ai<=bi<=50000,1<=ci<=bi-ai+1.表示在线段[ai,bi]上至少选ci个点,使被选出的点的个数最少而且满足所有的限制条件,输出这个最小值。
最小值→最大路。
在建图时需要注意,区间左闭右开或右闭左开(否则相邻区间公共顶点会被算两次)。
两个隐藏条件也要用于建图,否则基本不能更新全。
第一个是dis[i+1]-dis[i]>=0;
第二个是dis[i+1]-dis[i]<=1;
再根据题目输入条件求最大路即可。
/*
time:219ms
memory:2520k
*/
#include<cstdio>
#include<cstring>
#define N 50010
int st=50010,en,cnt,m,dis[N],head[N],que[N];
bool in[N];
struct edges {
int t,w,xt;
} edge[200010];
inline void add(int u,int v,int w) {
edge[++cnt].t=v;
edge[cnt].w=w;
edge[cnt].xt=head[u];
head[u]=cnt;
}
inline int spfa() {
int hd=0,tl=0;
que[hd]=st;
dis[st]=0;
while(hd<=tl) {
int x=que[hd++%N];
in[x]=0;
for(int it=head[x]; it; it=edge[it].xt) {
int v=edge[it].t;
int len=dis[x]+edge[it].w;
if(len>dis[v]) {
dis[v]=len;
if(!in[v]) {
in[v]=1;
que[++tl%N]=v;
}
}
}
}
return dis[en];
}
int main() {
memset(dis,-31,sizeof(dis));//-505290271
scanf("%d",&m);
while(m--) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u-1,v,w);
if(u-1<st) st=u-1;
if(v>en) en=v;
}
for(int i=st; i<en; i++) {
add(i+1,i,-1);
add(i,i+1,0);
}
printf("%d",spfa());
}