ACM: 图论题 poj 1201 差分约束

来源:互联网 发布:java酒店管理系统程序 编辑:程序博客网 时间:2024/05/18 13:24
Intervals
 
Description
You are given n closed, integerintervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1,..., cn from the standard input,
computes the minimal size of a set Z of integers which has at leastci common elements with interval [ai, bi], for eachi=1,2,...,n,
writes the answer to the standard output.

Input

The first line of the inputcontains an integer n (1 <= n <=50000) -- the number of intervals. The following n lines describethe intervals. The (i+1)-th line of the input contains threeintegers ai, bi and ci separated by single spaces and such that 0<= ai <= bi <= 50000and 1 <= ci <= bi - ai+1.

Output

The output contains exactly oneinteger equal to the minimal size of set Z sharing at least cielements with interval [ai, bi], for each i=1,2,...,n.

Sample Input

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

Sample Output

6

 

题意: 给出N个闭区间[ai, bi], 每个区间有一个ci表示集合Z在区间[ai, bi]内有ci个公共元素,

     现在问你在集合Z上至少有多少个公共元素.

 

解题思路:

    1. 明显是差分约束题目, dist[i]表示源点到i的公共元素个数, t_min和t_max分别表示这个集合Z

       的上下界, dist[t_max]-dist[t_min]就是区间中至少有多少个公共元素.

     2.题目有2个约束条件:

       dist[bi+1] - dist[ai] >= ci; ==>dist[bi+1] >= dist[ai]+ci

       0 <= dist[i+1] - dist[i] <= 1;

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAX 50005
const int INF = (1<<28);

struct node
{
 int v;
 int w;
 int next;
}edges[MAX*3];

int n, num;
int first[MAX];
int t_max, t_min;

inline void add(int u, int v, int w)
{
 edges[num].v = v;
 edges[num].w = w;
 edges[num].next = first[u];
 first[u] = num++;
}

int spfa()
{
 queue qu;
 int dist[MAX];
 bool vis[MAX];
 memset(vis, false, sizeof(vis));
 for(int i = t_min; i <= t_max;++i)
  dist[i] = -INF;
 dist[t_min] = 0;
 qu.push(t_min);

 while( !qu.empty() )
 {
  int u = qu.front();
  qu.pop();
  vis[u] = false;
  for(int e = first[u]; e != -1;e = edges[e].next)
  {
   if(dist[edges[e].v] < dist[u]+edges[e].w )
   {
    dist[edges[e].v]= dist[u]+edges[e].w;
    if(!vis[edges[e].v] )
    {
     vis[edges[e].v]= true;
     qu.push(edges[e].v);
    }
   }
  }
 }
 return dist[t_max]-dist[t_min];
}

int main()
{
 int i;
// freopen("input.txt", "r", stdin);
 while(scanf("%d", &n) !=EOF)
 {
  memset(first, -1,sizeof(first));
  t_max = -1;
  t_min = INF;
  int u, v, w;
  for(i = 0; i <n; ++i)
  {
   scanf("%d %d%d", &u, &v,&w);
   v++;
   if( t_max< v ) t_max = v;
   if( t_min> u ) t_min = u;
   add(u, v,w);
  }

  for(i = t_min; i< t_max; ++i)
  {
   add(i, i+1,0);
   add(i+1, i,-1);
  }

  printf("%d\n",spfa());
 }
 return 0;
}

0 0
原创粉丝点击