Intervals
Description
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, their end points and integers c1, ..., cn from the standard input, computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n, writes the answer to the standard output.
Input
The first line of the input contains an integer n (1 <= n <= 50000) -- the number of intervals. The following n lines describe the intervals. The (i+1)-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <= ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
题意:n个区间,[a[i],b[i]]每个区间至少选c[i]个数。求满足条件的最小数的个数
题解:设f[i]为[1,i]中选的数的个数,那么对于区间[a,b]来说,f[b]-f[a-1]>=c;
f[b]>=f[a-1]+c;另外,0<=f[i]-f[i-1]<=1;spfa算法+差分约束
#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
#define MAX 50005
using namespace std;
int head[50005];
int dest[50005];
int visit[50005];
struct lmx{
int v;
int next;
int val;
};
lmx lm[MAX*4];
int k,nmin,nmax;
void add(int u,int v,int w)
{
lm[k].v=v;
lm[k].val=w;
lm[k].next=head[u];
head[u]=k++;
}
void spfa()
{
queue<int> s;
int i;
memset(visit,0,sizeof(visit));
for(i=0;i<=50000;i++) dest[i]=-50000;
dest[nmin]=0;
visit[nmin]=1;
s.push(nmin);
while(!s.empty())
{
int top=s.front();
s.pop();
for(i=head[top];i!=-1;i=lm[i].next)
{
if(dest[lm[i].v]<dest[top]+lm[i].val)
{
dest[lm[i].v]=dest[top]+lm[i].val;
if(visit[lm[i].v]==0)
{
visit[lm[i].v]=1;
s.push(lm[i].v);
}
}
}
visit[top]=0;
}
}
int main()
{
int n,a,b,c,i;
while(scanf("%d",&n)!=EOF)
{
nmin=50005;
nmax=0;
k=0;
memset(head,-1,sizeof(head));
while(n--)
{
scanf("%d %d %d",&a,&b,&c);
if(nmin>a) nmin=a;
if(nmax<b+1) nmax=b+1;
add(a,b+1,c);
}
for(i=nmin;i<=nmax;i++)
{
add(i,i-1,-1);
add(i-1,i,0);
}
spfa();
printf("%d\n",dest[nmax]);
}
return 0;
}
为了明天所以选择坚定的执着今天。