版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42369449/article/details/82811054
算法:差分约束
难度:NOIP
3个约束不等式
d[R] - d[L-1] >= w (1)
d[i] - d[i-1] >= 0 (2)
d[i-1] - d[i] >= -1 (3)
(2),(3)不等式的来源是,考虑到每个点有选和不选两种状态,所以d[i]和d[i-1]需要满足以下不等式: 0 <= d[i] - d[i-1] <= 1 (即第i个数选还是不选)
spfa跑最长路即可
注意:后来加边时取不到r
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <queue>
#include <deque>
#define N 50005
#define ll long long
using namespace std;
struct node
{
int next;
int to;
int val;
}edge[N<<2];
int head[N],vis[N],dis[N];
int cnt=1;
void init()
{
cnt=1;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[cnt].next=head[u];
edge[cnt].to=v;
edge[cnt].val=w;
head[u]=cnt++;
}
void spfa(int rt)
{
deque <int> Q;
dis[rt]=0;
vis[rt]=1;
Q.push_front(rt);
while(!Q.empty())
{
int u=Q.front();
Q.pop_front();
for(int i = head[u];i != -1;i=edge[i].next)
{
int to=edge[i].to;
if(dis[to]<dis[u]+edge[i].val)
{
dis[to]=dis[u]+edge[i].val;
if(!vis[to])
{
vis[to]=1;
//Q.push(to);
if(!Q.empty()&&dis[to]>dis[Q.front()])
{
Q.push_front(to);
}else
{
Q.push_back(to);
}
}
}
}
vis[u]=0;
}
}
int main()
{
int n;
scanf("%d",&n);
init();
int l=0x3f3f3f3f,r=0;
for(int i = 1;i <= n;i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
add(x-1,y,w);
l=min(l,x-1);
r=max(r,y);
}
for(int i = l;i < r/*注意取不到“= ”!!!*/;i++)
{
add(i,i+1,0);
add(i+1,i,-1);
}
spfa(l);
printf("%d\n",dis[r]);
return 0 ;
}