Intervals(poj1201

                         题目传送门

Intervals
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 28676   Accepted: 11065

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

 

 大意:给你n个区间,每个区间[li,ri]至少选出ci个数,问最小可行集合的大小。

  题解:

  一道典型的差分约束问题。(没学过差分约束的同学可以看这篇讲解:传送门

  我们设d[i]表示前i个数中被选的数的个数,则区间限制变成了d[ri]-d[li-1]>=ci. 建图之后设跑最长路即可。

  需要注意的是题目中的隐含条件:d[i]>=d[i-1],d[i-1]>=d[i]-1

  又由于[0,x]这样的区间会出现d[-1]这样的情况,所以我们稍作改变,让d[i]表示前i-1个数中被选数的个数,起点为d[0]=0.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<bitset>
 7 #define LL long long
 8 #define RI register int
 9 using namespace std;
10 const int INF = 0x7ffffff ;
11 const int N = 50000 + 10 ;
12 
13 inline int read() {
14     int k = 0 , f = 1 ; char c = getchar() ;
15     for( ; !isdigit(c) ; c = getchar())
16       if(c == '-') f = -1 ;
17     for( ; isdigit(c) ; c = getchar())
18       k = k*10 + c-'0' ;
19     return k*f ;
20 }
21 struct Edge {
22     int to, next, val ;
23 }e[N<<2] ;
24 int n ; int head[N], dis[N], num[N] ;
25 inline void add_edge(int x,int y,int z) {
26     static int cnt = 0 ;
27     e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt, e[cnt].val = z ;
28 }
29 
30 inline bool spfa() {
31     for(int i=0;i<N;i++) dis[i] = INF ;
32     queue<int>q ; q.push(0), dis[0] = 0 ; bitset<N>inq ; inq[0] = 1 ;
33     while(!q.empty()) {
34         int x = q.front() ; q.pop() ;
35         if(num[x] > n) return 0 ;
36         for(int i=head[x];i;i=e[i].next) {
37             int y = e[i].to ; 
38             if(dis[y] > dis[x]+e[i].val) {
39                 dis[y] = dis[x]+e[i].val ;
40                 if(!inq[y]) {
41                     q.push(y) ; inq[y] = 1 ; num[y]++ ;
42                 }
43             }
44         }
45         inq[x] = 0 ;
46     }
47     return 1 ;
48 }
49 
50 int main() {
51     n = read() ; int maxx = 0, minn = INF ;
52     for(int i=1;i<=n;i++) {
53         int x = read(), y = read(), z = read() ;
54         maxx = max(maxx,y+1), minn = min(minn,x) ;
55         add_edge(x,y+1,-z) ;
56     }
57     add_edge(0,minn,0) ;
58     for(int i=minn;i<=maxx;i++) add_edge(i,i+1,0), add_edge(i+1,i,1) ;
59     if(!spfa()) {
60         printf("No solution!") ; return 0 ;
61     } 
62     printf("%d",-dis[maxx]) ;
63     return 0 ;
64 }
原文地址:https://www.cnblogs.com/zub23333/p/8830281.html