题意;给出一些闭区间[a,b],在区间中取c个数,求在所有的区间中,所取得数的最小个数
思路:差分约束 + spfa 求最大路径
#include<iostream>
#include<queue>
using namespace std;
#define inf 0x1fffffff
int visited[50010],dist[50010],adj[50010];
int size;
struct node
{
int e,v,next;
}head[5001000];
void add_edge(int s,int e,int v)
{
head[size].e = e;
head[size].v = v;
head[size].next = adj[s];
adj[s] = size++;
}
void spfa(int a,int b)
{
int i;
for(i = a;i <= b;i++)
dist[i] = -inf;
dist[a] = 0;
queue<int> que;
que.push(a);
visited[a] = 1;
int u,v,w;
while(!que.empty())
{
u = que.front();
que.pop();
visited[u] = 0;
for(i = adj[u];i != -1;i = head[i].next)
{
w = head[i].v;
v = head[i].e;
if(dist[v] < dist[u] + w)
{
dist[v] = dist[u] + w;
if(!visited[v])
{
visited[v] = 1;
que.push(v);
}
}
}
}
}
int main()
{
int n,i;
scanf("%d",&n);
int max = -1;
int min = inf;
int a,b,c;
memset(adj,-1,sizeof(adj));
size = 0;
for(i = 1;i <= n;i++)
{
scanf("%d%d%d",&a,&b,&c);
add_edge(a,b+1,c);
if(a < min) min = a;
if(b+1 > max) max = b+1;
}
for(i = min;i <= max;i++)
{
add_edge(i,i+1,0);
add_edge(i+1,i,-1);
}
spfa(min,max);
printf("%d\n",dist[max]);
return 0;
}