差分约束题目。首先建图,我们采用num[n]表示[0 , n]区间的点的个数。然后这题我们就能很容易给出方程即:num[x] - num[y-1] >= c;转化为: num[x] - c >= num[y-1] ,这样我们就可以建立出对应的图了。但是这个图还不完整,因为还有些隐藏的条件没被发掘出来,我们需要进一步的挖掘。对于区间[i , i] 的点的个数肯定是大于等于0,小于等于1,对应的方程就是:num[i+1] - num[i]>=0&& num[i+1]-num[i]<=1,这样我们就可以将图完全化了。但是我们发现这样会有150000多条边,然后又50000个点,这样用bellman会超时。因为这个题目必定有解,可以这样考虑下,如果当所有的边都不会对其中的点进行优化的时候,那么就到达稳定状态,这样我们就可以将bellman算法算法外重循环更改一下做个判断:如果没有松弛操作的话,我们就直接退出循环。时间:375ms代码如下:
#include<stdio.h>
#include<string.h>
#define MAXN 50005
int n ;
int m ;
int nmax ;
struct Node{
int s ;
int e ;
int w ;
}edge[MAXN * 3];
int num[MAXN] ;
int len ;
void read(){
scanf("%d" , &n) ;
int i ;
int p ;
int q ;
int w ;
len = 0 ;
nmax = 0 ;
memset(num , 0 , sizeof(num)) ;
for(i = 0 ; i < n ; i ++){
scanf("%d %d %d" , &p , &q , &w) ;
if(nmax < p)
nmax = p ;
if(nmax < q)
nmax = q ;
if(p == 0){
num[q] = w ;
continue ;
}
edge[len].e = p - 1 ;
edge[len].s = q ;
edge[len].w = -w ;
len ++ ;
}
nmax = nmax ;
for(i = 0 ; i < nmax - 1 ; i ++){
edge[len].s = i ;
edge[len].e = i + 1 ;
edge[len].w = 1 ;
len ++ ;
}
for(i = 0 ; i < nmax - 1 ; i ++){
edge[len].s = i + 1 ;
edge[len].e = i ;
edge[len].w = 0 ;
len ++ ;
}
}
void bellman(){
bool flag = true ;
while(flag){
flag = false ;
for(int j = 0 ; j < len ; j ++){
if(num[edge[j].e] > num[edge[j].s] + edge[j].w){
num[edge[j].e] = num[edge[j].s] + edge[j].w ;
flag = true ;
}
}
}
}
int main(){
read() ;
bellman() ;
printf("%d\n" , num[nmax] - num[0]) ;
return 0 ;
}