输入n个区间和n个数字c
区间[a,b]间至少有c个数字
s[i]表示从0到i之间共有多少个整数
约束条件
s[b]-s[a] >= c
0 <= s[i+1]-s[i] <= 1
区间[a,b]间至少有c个数字
s[i]表示从0到i之间共有多少个整数
约束条件
s[b]-s[a] >= c
0 <= s[i+1]-s[i] <= 1
要求同时满足这些区间要求的最少的元素个数
>=,求最小值,做最长路;
#include<stdio.h>
#include<queue>
#include<cstring>
using namespace std;
#define maxn 50000+10
#define inf 0xfffffff
#define clr(a,b) (memset(a,b,sizeof(a)))
struct node{
int to,w,next;
}edge[3*maxn];
int head[maxn],dis[maxn];
bool used[maxn];
int id,n;
void addedge(int u,int v,int c)
{
edge[id].to=v;
edge[id].w=c;
edge[id].next=head[u];
head[u]=id++;
}
void spfa(int u)
{
for(int i=0;i<maxn;i++)
dis[i]=-inf;
dis[u]=0;
queue<int>q;
q.push(u);
used[u]=true;
while(!q.empty())
{
int s=q.front();
q.pop();
used[s]=false;
for(int i=head[s];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]<dis[s]+edge[i].w)
{
dis[v]=dis[s]+edge[i].w;
if(!used[v])
{
used[v]=true;
q.push(v);
}
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
id=0;
int right=-inf,left=inf;
clr(head,-1);
clr(used,false);
for(int i=1;i<=n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
b++;
if(left>a) left=a;
if(right<b) right=b;
addedge(a,b,c);
}
for(int i=left;i<right;i++)
{
addedge(i,i+1,0);
addedge(i+1,i,-1);
}
spfa(left);
printf("%d\n",dis[right]);
}
return 0;
}