差分约束就是把不等式似的的东西转化为最短路求解,格式是所有式子都是两个未知数的差小于等于某个常数的就算,当然大于等于也可以,本题就是大于等于,乘-1就好~
1201题意:
[ai,bi]上至少要选择ci个整数点,可以在区间内任意取不重复的点,问最少选多少个点,这么些区间有重合部分,所以,列不等式啦
s[bi]-s[ai-1]>=ci
s[i]-s[i-1]<=1;
s[i]-s[i-1]>=0
据说一般差分约束系统是有负权边的,所以用可以判断的spfa
/*
Sbi - Sai >= ci
Si - Si-1 >= 0
Si-1 - Si >= -1
*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define maxN 50005
#define INF 1000000007
struct EDGE//使用邻接表存边
{
int v;
int cost;
int next;
}edge[3*maxN];
int first[maxN],d[maxN],visit[maxN];
int e,n,maxx,minn;
void AddEdge(int a,int b,int c)//添加新边
{
edge[e].v=b;
edge[e].cost=c;
edge[e].next=first[a];
first[a]=e++;
}
void SPFA()
{
for(int i=minn;i<=maxx;i++)
d[i] = -INF;
d[minn] = 0;
queue<int>q;
q.push(minn);
while(!q.empty())
{
int x=q.front();
q.pop();
visit[x]=0;
for(int e=first[x];e!=-1;e=edge[e].next)
if(d[edge[e].v]<d[x]+edge[e].cost)
{
d[edge[e].v]=d[x]+edge[e].cost;
if(!visit[edge[e].v])
{
q.push(edge[e].v);
visit[edge[e].v]=1;
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int a,b,c;
e=0;
minn = INF;
maxx = -INF;
memset(first,-1,sizeof(first));
memset(visit,0,sizeof(visit));
memset(edge,0,sizeof(edge));
for(int i=0;i<n;i++)
{
scanf("%d%d%d", &a,&b,&c);//题目条件的边
AddEdge(a,b+1,c);
minn=minn<a?minn:a;//在这里记录最小值和最大值
maxx=maxx>a+1?maxx:a+1;
}
for(int i=minn;i<maxx;i++)//添加新边
{
AddEdge(i,i+1,0);
AddEdge(i+1,i,-1);
}
SPFA();
printf("%d\n",d[maxx]);
}
return 0;
}