您的位置:首页 > 其它

ACM: 图论题 poj 1201 差分约束

2016-05-19 23:26 309 查看
[align=center]Intervals[/align]
 
Description
You are given n closed, integer
intervals [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 least
ci common elements with interval [ai, bi], for each
i=1,2,...,n,

writes the answer to the standard output.

Input

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

The output contains exactly one
integer equal to the minimal size of set Z sharing at least ci
elements 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: