POJ 1201 差分约束(集合最小元素个数)

题意:
      给你一个集合,然后有如下输入,a ,b ,c表示在范围[a,b]里面有至少有c个元素,最后问你整个集合最少多少个元素。

思路:
      和HDU1384一模一样,首先这个题目可以用差分约束来解决,是大于等于所以跑最长路(如果非要跑最短路建-权也可以),说下建图,首先我们把每个区间抽象出来,区间的两个端点之间的元素个数 [a ,b] = c 可以抽象成 点a,和点(b + 1)之间的距离 大于等于c,那么这样就可以把输入建进去了,还有个关键的地方就是题目的隐含条件,一般的查分约束的关键都是在于找隐含条件,这个题目的隐含条件就是相邻的

两个点的元素个数 >= 0 && <= 1,其他的没啥了。


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

#define N_node 55000
#define N_edge 210000
#define INF 100000000000000

using namespace std;

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

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

void add(int a ,int b ,__int64 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;
   int mark[N_node] = {0};
   int in[N_node] = {0};
   s_x[s] = 0;
   mark[s] = in[s] = 1;
   queue<int>q;
   q.push(s);
   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;
                q.push(xin);
                if(++in[xin] > n) return 0;
             }
          }
        }
   }
   return 1;
}

int maxx(int x ,int y)
{
    return x > y ? x : y;
}
int minn(int x ,int y)
{
    return x < y ? x : y;
}

int main ()
{
    int n ,a ,b ,i;
    __int64 c;
    while(~scanf("%d" ,&n))
    {
       memset(list ,0 ,sizeof(list));
       tot = 1;
       int Max = 0 ,Min = 100000000;
       for(i = 1 ;i <= n ;i ++)
       {
          scanf("%d %d %I64d" ,&a ,&b ,&c);
          b ++;
          add(a ,b ,c);
          Max = maxx(Max ,b);
          Min = minn(Min ,a);
       }
       for(i = Min ;i <= Max ;i ++)
       {
          add(i - 1 ,i ,0);
          add(i ,i - 1 ,-1);
       }
       spfa(Min ,Max);
       printf("%I64d
" ,s_x[Max]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/csnd/p/12063050.html