此题是 POJ 1716的加强版。
题意:给定n个整数区间,求一整数集合,使得任意区间中至少有ci个数在集合中,求集合中最少包含的元素个数。
建立差分约束系统:d[bi+1]-d[ai]>=ci ,0<=d[i+1]-d[i]<=1,d[k]为在区间[0,k-1]中选取的元素个数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> #include <queue> using namespace std; #define N 50010 #define M 200010 #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define INF 0x3fffffff int n,s,t; int d[N],inq[N]; int first[N],next[M],v[M],w[M],e; void init() { memset(first,-1,sizeof(first)); e=0; s=N; t=0; } void insert(int a,int b,int c) { v[e]=b; w[e]=c; next[e]=first[a]; first[a]=e++; } void spfa() { queue<int> q; int a,b,i; memset(inq,0,sizeof(int)*(t+5)); for(int i=s;i<=t;i++) d[i]=INF; d[s-1]=0; q.push(s-1); inq[s-1]=1; while(!q.empty()) { a=q.front(),q.pop(); inq[a]=0; for(i=first[a];i!=-1;i=next[i]) { b=v[i]; if(d[b]>d[a]+w[i]) { d[b]=d[a]+w[i]; if(inq[b]==0) inq[b]=1,q.push(b); } } } } int main() { int i; int a,b,c; while(~scanf("%d",&n)) { init(); for(i=0;i<n;i++) { scanf("%d%d%d",&a,&b,&c); s=MIN(s,MIN(a,b)); t=MAX(t,MAX(a,b)); insert(a,b+1,-c); } s++,t++; for(i=s;i<t;i++) insert(i,i+1,0),insert(i+1,i,1); spfa(); printf("%d\n",-d[t]); } return 0; }