zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    经验:Library Cache Lock之异常分析-云和恩墨技术通讯精选
    Schnorr 签名算法与聚合签名
    5G 第五代移动通信网络
    《机器学习》周志华西瓜书习题参考答案:第9章
    启动tomcat,在黑色窗口中看到乱码
    Linux系统目录结构以及简单说明
    Linux系统目录结构以及简单说明
    锤子科技官网:问题整理及注意事项
    锤子科技官网:问题整理及注意事项
    锤子科技官网:问题整理及注意事项
  • 原文地址:https://www.cnblogs.com/zub23333/p/8830281.html
Copyright © 2011-2022 走看看