zoukankan      html  css  js  c++  java
  • POJ 1201 Intervals 差分约束

    description

    有$n$个区间 $[a_i, b_i]$, 以及$c_i$, 有一个整数集合Z, 要求对于每个区间$[a_i, b_i] 中的数不少于$c_i$个。

    Solution

    设$s_k$ 表示前k个数至少要选几个, 显然有$s[b_i] - s[a_i - 1] >= c_i$, 然后就是一个很显然的差分约束

    另外还需满足: $s_{k+1} - s_k >= 0$, $s_{k+1} - s_k <= 1$

    所以从$a_i - 1$ 向 $b_i$连一条长度为$c_i$的边

    从$k$向$k+1$连长度为$0$ 的边

    从$k+1$向$k$连长度为$-1$的边

    跑一遍最长路即可求出答案

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 #define rd read()
     6 #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
     7 #define per(i,a,b) for(int i = (a); i >= (b); --i)
     8 using namespace std;
     9 
    10 const int N = 5e5 + 1e4;
    11 const int M = 3e6;
    12 const int inf = ~0U >> 2;
    13 
    14 int n, dis[N], vis[N], cnt[N];
    15 int tot, head[N];
    16 
    17 queue<int> q;
    18 
    19 struct edge {
    20     int nxt, to, val;
    21 }e[M];
    22 
    23 int read() {
    24     int X = 0, p = 1; char c = getchar();
    25     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    26     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    27     return X * p;
    28 }
    29 
    30 void add(int u, int v, int val) {
    31     e[++tot].to = v;
    32     e[tot].val = val;
    33     e[tot].nxt = head[u];
    34     head[u] = tot;
    35 }
    36 
    37 int spfa() {
    38     q.push(0);
    39     dis[0] = 0;
    40     for(int u; !q.empty();) {
    41         u = q.front(); q.pop();
    42         vis[u] = 0;
    43         for(int i = head[u]; i; i = e[i].nxt) {
    44             int nt = e[i].to;
    45             if(dis[nt] >= dis[u] + e[i].val) continue;
    46             dis[nt] = dis[u] + e[i].val;
    47             if(!vis[nt]) vis[nt] = 1, q.push(nt);
    48         }
    49     }
    50     return dis[(int)5e5 + 1];
    51 }
    52 
    53 int main()
    54 {
    55     n = rd;
    56     for(int i = 0; i <= 5e5; ++i) {
    57         add(i, i + 1, 0); add(i + 1, i, -1);
    58     }
    59     memset(dis, -1, sizeof(dis));
    60     rep(i, 1, n) {
    61         int a = rd, b = rd, c = rd;
    62         add(a, b + 1, c);
    63     }
    64     printf("%d\n", spfa());
    65 }
    View Code
  • 相关阅读:
    构造函数与其他方法的区别
    记录点复习题目和linux学习
    找点面试题目
    linux代码常用查询!!!!!!!!!!!!
    python复习
    明天面试今天赶紧准备下
    文都计算机考研课程
    是时候刷笔试题目了
    倒排索引
    总结算法课程
  • 原文地址:https://www.cnblogs.com/cychester/p/9574192.html
Copyright © 2011-2022 走看看