Intervals poj 1201 差分约束系统

Intervals
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 22503   Accepted: 8506

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

Source

 
设   s[i]表示集合中小于等于i的元素个数,  u   v   w      s[v]-s[u-1]>=w;
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <string>
  7 #include <vector>
  8 #include <set>
  9 #include <map>
 10 #include <queue>
 11 #include <stack>
 12 #include <sstream>
 13 #include <iomanip>
 14 using namespace std;
 15 const int INF=0x4fffffff;
 16 const int EXP=1e-6;
 17 const int MS=50005;
 18 
 19 struct edge
 20 {
 21       int u,v,w;
 22 }edges[10*MS];
 23 
 24 int maxv,minv;
 25 int dis[MS];
 26 int esize,n;
 27 
 28 bool bellman()
 29 {
 30       memset(dis,0,sizeof(dis));
 31       bool flag=true;
 32       int cnt=0;
 33       while(flag)
 34       {
 35             flag=false;   //表示没有更新了
 36 
 37             if(cnt++>n)    //更新次数大于n-1,
 38                   return false;
 39             for(int i=0;i<esize;i++)
 40             {
 41                   if(dis[edges[i].u]+edges[i].w<dis[edges[i].v])
 42                   {
 43                         dis[edges[i].v]=dis[edges[i].u]+edges[i].w;
 44                         flag=true;
 45                   }
 46             }
 47 
 48             //0<=s[i]-s[i-1]<=1      这些边可以不用存储
 49 
 50             //  i-1   -->i  1
 51 
 52             for(int i=minv;i<=maxv;i++)
 53             {
 54                   if(dis[i-1]+1<dis[i])
 55                   {
 56                         dis[i]=dis[i-1]+1;
 57                         flag=true;
 58                   }
 59             }
 60 
 61             //   i--> i-1   0
 62 
 63             for(int i=maxv;i>=minv;i--)
 64             {
 65                   if(dis[i]<dis[i-1])
 66                   {
 67                         dis[i-1]=dis[i];
 68                         flag=true;
 69                   }
 70             }
 71       }
 72       return true;
 73 }
 74 
 75 
 76 
 77 int main()
 78 {
 79       while(scanf("%d",&n)!=EOF)
 80       {
 81             int u,v,w;
 82             esize=0;
 83             maxv=0;
 84             minv=INF;
 85             for(int i=0;i<n;i++)
 86             {
 87                   scanf("%d%d%d",&u,&v,&w);
 88                   //   s[i]表示集合中小于等于i的元素个数
 89                   //s[v]-s[u-1]>=w;    v->u-1   -w;
 90                   edges[esize].u=v;
 91                   edges[esize].v=u-1;
 92                   edges[esize++].w=-w;
 93                   if(v>maxv)
 94                         maxv=v;
 95                   if(u<minv)
 96                         minv=u;
 97             }
 98             bellman();
 99             printf("%d\n",dis[maxv]-dis[minv-1]);
100       }
101       return 0;
102 }

 

 
 
posted @ 2015-03-28 23:10  daydaycode  阅读(152)  评论(0编辑  收藏  举报