【分析】
差分约束系统啦
如果大家对差分约束系统不了解,那么就去看一下我博客上的讲解吧。不了解这个是很难看懂分析的。
【传送门在此】
题意要求至少多少西瓜,所以应该是求单源最长路,我们可以把它翻过来转化为求单源最短路。
用 f[i] 表示1~i 这i块地中种植的西瓜总数,那么对于每一个条件:左端点为l,右端点为r,须种植d个瓜及以上,容易得到:
f[r]-f[l-1]>=d
根据上文介绍,为了转化为单源最短路问题,我们从 l-1 向 r 连一条长度为 -d 的边
还有隐含条件:
f[i]-f[i-1]>=0
f[i-1]>=f[i]-1
从 i-1 向 i 连一条长度为0的边,从 i 向 i-1 连一条长度为 1 的边。
下面就是简单的求单源最短路,然后输出 dis[n]
【代码】
//tyvj1415 西瓜种植
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define fo(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
vector <int> f[5001];
vector <int> l[5001];
int n,m,x,y,d;
int dis[5001],q[500001];
bool vis[5001];
int main()
{
memset(dis,0x7f,sizeof dis);
scanf("%d%d",&n,&m);
fo(i,1,n)
f[i-1].push_back(i),l[i-1].push_back(0),
f[i].push_back(i-1),l[i].push_back(1);
fo(i,1,m)
{
scanf("%d%d%d",&x,&y,&d);
f[x-1].push_back(y);
l[x-1].push_back(-d);
}
dis[0]=0;
vis[0]=1;
int h=0,t=1;
q[t]=0;
while(h<t)
{
int u=q[++h];
vis[u]=0;
int x=f[u].size()-1;
fo(i,0,x)
{
int v=f[u][i];
if(dis[v]>dis[u]+l[u][i])
{
dis[v]=dis[u]+l[u][i];
if(!vis[v])
vis[v]=1,q[++t]=v;
}
}
}
printf("%d\n",-dis[n]);
return 0;
}