poj 1201 intervals

Intervals
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 24152   Accepted: 9186

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


题解:差分约束系统。

之前提到过一道差分约束系统的题,说是用到了树状数组的思想。这道题也是一样的道理。每个点表示的是从开始到当前点中选定的数量。

一般的的差分约束系统的题都是要求  u-v<=x   可以转成u<=v+x的形式,最终通过最短路求解。

而这道题有点不同,他要求的是区间中的数量大于等于某值,即 [x,y] >=z    y-(x-1)>=z   y>=(x-1)+z  由(x-1)向y连边,然后跑最长路即可。另外主要这道题有一个隐藏条件,就是相邻的两个点记录的值的差应该是大于等于0,小于等于1的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
int point[1000003],v[1000003],c[1000003],next[1000003],tot=0,dis[1000003],maxn=0,can[1000003];
void add(int x,int y,int z)
{
  tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z; 
}
void spfa()
{
  queue<int> p; p.push(0); can[0]=1;
  while (!p.empty())
   {
   	 int now=p.front(); p.pop();
	 for (int i=point[now];i;i=next[i])
	  if (dis[v[i]]<dis[now]+c[i])
	  {
	  	 dis[v[i]]=dis[now]+c[i];
	  	 if (!can[v[i]])
	  	  {
	  	  	can[v[i]]=1;
	  	  	p.push(v[i]);
	  	  }
	  } 
	 can[now]=0; 
   }
}
int main()
{
  scanf("%d",&n);
  for (int i=1;i<=n;i++)
   {
   	int x,y,z;
   	scanf("%d%d%d",&x,&y,&z);
   	add(x,y+1,z);
   	maxn=max(maxn,y+1);
   }
  for (int i=0;i<maxn;i++)
   {
     add(i,i+1,0);
   	 add(i+1,i,-1);
   }
  memset(dis,128,sizeof(dis));
  dis[0]=0;
  spfa();
  cout<<dis[maxn]<<endl;
  return 0;
}



你可能感兴趣的:(poj 1201 intervals)