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;
}
posted @ 2013-10-05 13:26  forevermemory  阅读(249)  评论(0编辑  收藏  举报