• 【算法】区间(差分约束)


    题目

    给定 n 个区间 [ai,bi] 和 n 个整数 ci。

    你需要构造一个整数集合 Z,使得 ∀i∈[1,n],Z 中满足 ai≤x≤bi 的整数 x 不少于 ci 个。

    求这样的整数集合 Z 最少包含多少个数。

    输入格式

    第一行包含整数 n。

    接下来 n 行,每行包含三个整数 ai,bi,ci。

    输出格式

    输出一个整数表示结果。

    数据范围

    1 ≤ n ≤ 50000
    0 ≤ ai,bi ≤ 50000
    0 ≤ ci ≤ bi − ai + 1

    输入样例:
    1. 5
    2. 3 7 3
    3. 8 10 3
    4. 6 8 1
    5. 1 3 1
    6. 10 11 1
    输出样例:
    6

    思路

    按照样例,我们可以得到一张图。

     差分约束:

    (1)求不等式组的可行解

                    源点需要满足条件:从原点出发,一定可以走到所有边。

    步骤:

    【1】先将每个不等式 xi <= xj + ck,转化为一条从xj走到xi的,长度为ck的一条边。

    【2】找一个超级源点,使得该源点一定可以遍历到所有的边。

    【3】从源点求一遍单源最短路

            结果1:如果存在负环,则原不等式组一定无解。

            结果2:如果没有负环,则dist[ i ]就是原不等式组的一个可行解。

    (2)如何求最大值或者最小值,这里的最值指的是每个变量的最值

            结论:如果求的是最小值,则应该是求最长路;如果求的是最大值,则应该是求最短路。

            问题:如何转化x1 <= c,其中一个是常数这类不等式。

            方法:建立一个超级源点,然后建立0 -> i,长度是c的边即可。

    代码 

    1. #include
    2. using namespace std;
    3. const int N = 200000;
    4. int n;
    5. int h[N],e[N],ne[N],w[N],idx;
    6. int dist[N];
    7. bool st[N];
    8. void add(int a,int b,int c)
    9. {
    10. ne[idx] = h[a],e[idx] = b,w[idx] = c,h[a] = idx ++;
    11. }
    12. void spfa()
    13. {
    14. queue<int> q;
    15. dist[0] = 0;
    16. q.push(0);
    17. st[0] = true;
    18. while(!q.empty())
    19. {
    20. int t = q.front();
    21. q.pop();
    22. st[t] = false;
    23. for(int i = h[t]; ~i ; i = ne[i])
    24. {
    25. int j = e[i];
    26. if(dist[j] < dist[t] + w[i])
    27. {
    28. dist[j] = dist[t] + w[i];
    29. if(!st[j])
    30. {
    31. st[j] = true;
    32. q.push(j);
    33. }
    34. }
    35. }
    36. }
    37. }
    38. int main()
    39. {
    40. memset(dist,-0x3f,sizeof dist);
    41. memset(h,-1,sizeof h);
    42. cin >> n;
    43. for(int i = 1; i <= 50001; i ++)
    44. {
    45. add(i-1,i,0);
    46. add(i,i-1,-1);
    47. }
    48. for(int i = 1; i <= n; i ++)
    49. {
    50. int a,b,c;
    51. cin >> a >> b >> c;
    52. add(a,b + 1,c);
    53. }
    54. spfa();
    55. cout << dist[50001] << endl;
    56. return 0;
    57. }

    题目来自:https://www.acwing.com/

  • 相关阅读:
    pgsql 报错 later table “drop column” is not supported now
    vue+element 树形结构 改成懒加载模式(原理element有),这里只做个人理解笔记
    图论(链式前向星、最短路、最小生成树)
    彻底搞懂原生事件流和 React 事件流
    SpringCache缓存处理
    酷克数据亮相第13届PostgreSQL中国技术大会,获数据库杰出贡献奖
    RNA甲基化修饰种类
    java8新特性——Function&Stream&Optional
    联盟认证 | 聚铭网络正式成为中国反网络病毒联盟成员
    mysql不区分大小写配置
  • 原文地址:https://blog.csdn.net/littlegengjie/article/details/134410313