zoukankan      html  css  js  c++  java
  • week8-A-区间选点

    题意:

    给定一个数轴上的 n 个区间,要求在数轴上选取最少的点使得第 i 个区间 [ai, bi] 里至少有 ci 个点

    使用差分约束系统的解法解决这道题
    Input

    输入第一行一个整数 n 表示区间的个数,接下来的 n 行,每一行两个用空格隔开的整数 a,b 表示区间的左右端点。1 <= n <= 50000, 0 <= ai <= bi <= 50000 并且 1 <= ci <= bi - ai+1。

    Output

    输出一个整数表示最少选取的点的个数

    Sample Input

    5
    3 7 3
    8 10 3
    6 8 1
    1 3 1
    10 11 1

    Sample Output

    6

    My Solution :

     差分约束思想:

    关键在于构造不等式组(包括解的合理性)==> 单源最短路

    对于差分约束中的每一个不等式约束 xi - xj <= c, 都可以移项变形为xi <=xj +c
    与图的最短路问题中的松弛操作类似    (dis [ i ] <= dis [ j ] + w( i , j )

    具体做法:

    记 dis [ i ]表示数轴上 [ 0,i ]之间选点的个数
    对于第i个区间 [ai,bi] 需要满足 dis [bi] - dis [ai-1]>=ci,

    注意:为保证dis有意义:需满足0<= dis [ i ] - dis [ i-1 ] <= 1

    Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue> 
     6 using namespace std;
     7 
     8 int maxn,tot;
     9 int head[50010],dis[50010];
    10 queue<int>q;
    11 
    12 struct node{
    13     int v,x;
    14     int next;
    15 }e[50010*3];
    16 
    17 bool b[50010];
    18 
    19 void add(int u,int v,int w)
    20 {
    21     e[++tot].v=v;
    22     e[tot].x=w;
    23     e[tot].next=head[u];
    24     head[u]=tot;
    25 }
    26 void spfa()
    27 {
    28     memset(dis,-1,sizeof dis);
    29     q.push(0);
    30     dis[0]=0;
    31     
    32     while(!q.empty())
    33     {
    34         int u=q.front();q.pop();b[u]=0;
    35         for(int i=head[u];i;i=e[i].next)
    36         {
    37             int v=e[i].v;
    38             if(dis[v]<dis[u]+e[i].x)     //松弛操作 
    39             {
    40                 dis[v]=dis[u]+e[i].x;
    41                 if(!b[v])
    42                  b[v]=1,q.push(v);
    43             }
    44         }
    45     }
    46     return ;
    47 }
    48 int main()
    49 {
    50     int n,a,b,c;
    51     scanf("%d",&n);
    52     for(int i=0;i<n;i++)
    53     {
    54         scanf("%d%d%d",&a,&b,&c);
    55         
    56         add(a,++b,c);
    57         maxn=std::max(maxn,b);
    58     }
    59     for(int i=1;i<=maxn;i++)
    60     {
    61         add(i-1,i,0);
    62         add(i,i-1,-1);
    63     }
    64     spfa();
    65     printf("%d",dis[maxn]);
    66     
    67     return 0;
    68 }
  • 相关阅读:
    leetcode刷题笔记303题 区域和检索
    leetcode刷题笔记301题 删除无效的括号
    20201208日报
    20201118日报
    20201117日报
    20201116日报
    20201115日报
    20201114日报
    20201113日报
    20201112日报
  • 原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/12717950.html
Copyright © 2011-2022 走看看