题目大意:
给你N个区间,[a,b]要求你在每个区间内至少找C个数,要求你求出一个集合,集合内的数包含所有满足条件的区间内的数,输出这个集合内的元素的个数即可。
解题思路:
利用差分约束的思想,构造不等式组:
a-(b+1)<=-c
i-1-i<=0;
i-(i-1)<=1;
代码:
#include<stdio.h>
#include<queue>
using namespace std;
const int inf = 1<<30;
const int N = 50010;
struct node
{
int to;
int dis;
int next;
};
node edg[N*4];
int head[N],h;
void add(int a,int b,int d)
{
edg[h].to=b;
edg[h].dis=d;
edg[h].next=head[a];
head[a]=h;
h++;
}
int dis[N];
bool in_q[N];
void spfa(int st,int ed)
{
queue<int> q;
q.push(st);
dis[st]=0;
in_q[st]=true;
int v,k,cur;
while(!q.empty())
{
v=q.front();
// if(v==ed)
// return ;
q.pop();
in_q[v]=false;
for(k=head[v];k!=-1;k=edg[k].next)
{
// puts("**");
cur=edg[k].to;
if(dis[cur]>dis[v]+edg[k].dis)
{
dis[cur]=dis[v]+edg[k].dis;
if(!in_q[cur])
{
q.push(cur);
in_q[cur]=true;
}
}
}
}
}
void init()
{
int i;
for(i=0;i<N;i++)
{
head[i]=-1;
dis[i]=inf;
in_q[i]=false;
}
h=0;
}
int main()
{
int n;
int a,b,d;
int i,st,ed;
while(scanf("%d",&n)!=EOF)
{
init();
st=inf;
ed=-inf;
for(i=0;i<n;i++){
scanf("%d%d%d",&a,&b,&d);
add(a,b+1,-d);
st=a<st?a:st;
ed=ed>(b+1)?ed:(b+1);
}
for(i=ed;i>st;i--)
{
add(i-1,i,0);
add(i,i-1,1);
}
spfa(st,ed);
printf("%d\n",-dis[ed]);
}
}