zoukankan      html  css  js  c++  java
  • POJ 1716 区间最小点个数

    题意:
         给你n个区间,每个区间最少取两个元素,问你所有区间最少取几个元素(可以满足
    每个区间最少两个元素)。

     

    思路:
         这个题目感觉挺巧妙的,之前在杭电上做过这个题目,这个题目可以用查分约束来做
    ,对于每一个区间a,b我们可以这样 b - a >= 2 那么建图a->b 长度是2,全建完之后不要忘记题目的隐含条件,查分约束中隐含条件很重要,这个题目的隐含条件就是相邻的两个点之间的个数大于等于0,小于等于1,也就是  0 =< i - (i - 1) <= 1,然后拆成两部分,对于i - (i - 1) >= 0  建立 (i - 1)-> i 长度0,对于i - (i - 1) <= 1先转换成 (i - 1) - i >= -1 建立 i -> (i - 1) 长度是-1,然后以最小点为起点一边最长路,在查分约束中要记住,求最小就跑最长路,求最大就跑最短路,其他的没啥。

     

    #include<stdio.h>
    #include<string.h>
    #include<queue>

    #define N_node 11000
    #define N_edge 33000
    #define INF 1000000000

    using namespace std;

    typedef struct
    {
       int to ,next ,cost;
    }STAR;


    STAR E[N_edge];
    int list[N_node] ,tot;
    int mark[N_node] ,mki[N_node] ,s_x[N_node];

    void add(int a ,int b ,int c)
    {
         E[++tot].to = b;
         E[tot].cost = c;
         E[tot].next = list[a];
         list[a] = tot;
    }

    bool spfa(int s ,int n)
    {
       for(int i = 0 ;i <= n ;i ++)
       s_x[i] = -INF ,mark[i] = mki[i] = 0;
       queue<int>q;
       q.push(s);
       s_x[s] = 0 ,mark[s] = mki[s] = 1;
       while(!q.empty())
       {
          int xin ,tou;
          tou = q.front();
          q.pop();
          mark[tou] = 0;
          for(int k = list[tou] ;k ;k = E[k].next)
          {
              xin = E[k].to;
              if(s_x[xin] < s_x[tou] + E[k].cost)
              {
                 s_x[xin] = s_x[tou] + E[k].cost;
                 if(!mark[xin])
                 {
                    mark[xin] = 1;
                    if(++mki[xin] > n) return 0;
                    q.push(xin);
                 }
               }
           }
       }
       return 1;
    }

    int main ()
    {
        int i ,a ,b ,n ,Min ,Max;
        while(~scanf("%d" ,&n))
        {
           Min = INF ,Max = -INF;
           memset(list ,0 ,sizeof(list)) ,tot = 1;
           for(i = 1 ;i <= n ;i ++)
           {
              scanf("%d %d" ,&a ,&b);
              b++;
              if(Min > a) Min = a;
              if(Max < b) Max = b;
              add(a ,b ,2);
           }
           for(i = Min ;i <= Max ;i ++)
           add(i - 1 ,i ,0) ,add(i ,i - 1 ,-1);
           spfa(Min ,Max);
           printf("%d " ,s_x[Max]);
        }
        return 0;
    }
          
          
      

  • 相关阅读:
    Ubuntu adb devices :???????????? no permissions (verify udev rules) 解决方法
    ubuntu 关闭显示器的命令
    ubuntu android studio kvm
    ubuntu 14.04版本更改文件夹背景色为草绿色
    ubuntu 创建桌面快捷方式
    Ubuntu 如何更改用户密码
    ubuntu 14.04 返回到经典桌面方法
    ubuntu 信使(iptux) 创建桌面快捷方式
    Eclipse failed to get the required ADT version number from the sdk
    Eclipse '<>' operator is not allowed for source level below 1.7
  • 原文地址:https://www.cnblogs.com/csnd/p/12062753.html
Copyright © 2011-2022 走看看