POJ1201 Intervals【SPFA】【差分约束】

Intervals

Time Limit: 2000MS
Memory Limit: 65536K

Total Submissions: 22307
Accepted: 8413

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

Source

Southwestern Europe 2002

题目大意:给你N个整数点构成的区间[ai,bi](ai,bi都为整数),在区间[ai,bi]上最少选ci个点。

ci可在区间[ai,bi]中随意取,但是不能重复。问:要满足在N个区间取点,至少要选多少个点。

思路:差分约束思想。设Si为前i项的整数个数,则S(bi) - S(ai-1) >= ci。还有两个隐含约束条件

S(i-1) - S(i) <= 0,S(i)-S(i-1) <= 1。把这三种约束构建一个差分约束系统,用SPFA求最短路径。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 50050;
const int INF = 0xffffff0;

struct EdgeNode
{
    int to;
    int w;
    int next;
}Edges[MAXN << 2];
int Head[MAXN],Dist[MAXN],vis[MAXN];

int SPFA(int Left,int Right)
{
    for(int i = Left; i <= Right+1; ++i)
        Dist[i] = INF;
    memset(vis,0,sizeof(vis));
    queue<int> Q;
    Q.push(Right);
    vis[Right] = 1;
    Dist[Right] = 0;
    while( !Q.empty() )
    {
        int u = Q.front();
        Q.pop();
        vis[u] = 0;
        for(int i = Head[u]; i != -1; i = Edges[i].next)
        {
            int temp = Dist[u] + Edges[i].w;
            if( temp < Dist[Edges[i].to])
            {
                Dist[Edges[i].to] = temp;
                if( !vis[Edges[i].to] )
                {
                    vis[Edges[i].to] = 1;
                    Q.push(Edges[i].to);
                }
            }
        }
    }
    return -Dist[Left];
}

int main()
{
    int N,Left,Right,a,b,c;
    while(~scanf("%d",&N))
    {
        Left = MAXN,Right = 0;
        memset(Head,-1,sizeof(Head));
        memset(Edges,0,sizeof(Edges));
        int id = 0;
        for(int i = 0; i < N; ++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            Edges[id].to = a;
            Edges[id].w = -c;
            Edges[id].next = Head[b+1];
            Head[b+1] = id++;
            if(a < Left)
                Left = a;
            if(b > Right)
                Right = b;
        }
        Right++;
        for(int i = Left; i < Right; ++i)
        {
            Edges[id].to = i;
            Edges[id].w = 0;
            Edges[id].next = Head[i+1];
            Head[i+1] = id++;

            Edges[id].to = i+1;
            Edges[id].w = 1;
            Edges[id].next = Head[i];
            Head[i] = id++;
        }

        printf("%d\n",SPFA(Left,Right));
    }

    return 0;
}
时间: 2024-08-10 17:17:00

POJ1201 Intervals【SPFA】【差分约束】的相关文章

POJ1201 Intervals (差分约束)

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 wh

POJ1201 Intervals 【差分约束】

题目链接 POJ1201 题解 差分约束 令\(a[i]\)表示是否选择\(i\),\(s[i]\)表示\(a[i]\)的前缀和 对\(s[i] \quad i \in [-1,50000]\)分别建立一个点 首先有 \[s[i] - s[i - 1] \ge 0\] \[s[i] - s[i - 1] \le 1\] 然后就是限制条件 \[s[b] - s[a - 1] \ge c\] 然后就没了 用\(spfa\)跑最长路 由于题目保证有解,所以不会存在正环 复杂度上界是\(O(nm)\)的

poj1201 Intervals【差分约束+SPFA】

转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4303365.html   ---by 墨染之樱花 题目链接:http://poj.org/problem?id=1201 题目描述:给出n个整数三元组(x,y,c),求一个整数集合Z,使其对每个前述三元组都满足在x与y之间(闭区间)的数的个数至少为c,求这个整数集合Z的最少有几个数 思路:利用差分约束系统求解.构造数列a1a2a3...an(其中ai只能为0或1,0表示i不在Z中,1表示i在

poj1201 Intervals,差分约束问题,spfa

题目大意: 有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该序列中处于[ai,bi]这个区间的整数至少有ci个.如果存在这样的序列,请求出满足题目要求的最短的序列长度是多少.如果不存在则输出 -1. 输入:第一行包括一个整数n,表示区间个数,以下n行每行描述这些区间,第i+1行三个整数ai,bi,ci,由空格隔开,其中0<=ai<=bi<=50000 而且 1<=ci<=bi-ai+1. 输出:一行,输出满足要求的序列的长度的最小值.

POJ1201 Intervals 【差分约束系统】

Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21591   Accepted: 8122 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 po

POJ1201:Intervals【差分约束】

题目大意:给出N个闭区间,每个区间给出一个ci值,让你找出最小的数集Z使得每个闭区间都有不少于ci个Z中的元素,求card(Z) 思路:06年集训队论文<浅析差分约束系统>有详细的解题,设Sn为[0,n]中Z中元素的个数,ai ,bi为区间的两个端点,则可列出以下不等式: 0<=Sn-S(n-1)<=1 S(bi+1)-S(ai)>=ci 然后就可以用差分约束做了,顺便提一下,如果要把0<=Sn-S(n-1)<=1这些边加进图中的话边集会非常的大,以至于一开始邻接

HDU 1384 Intervals【差分约束-SPFA】

类型:给出一些形如a−b<=k的不等式(或a−b>=k或a−b<k或a−b>k等),问是否有解[是否有负环]或求差的极值[最短/长路径].例子:b−a<=k1,c−b<=k2,c−a<=k3.将a,b,c转换为节点:k1,k2,k3转换为边权:减数指向被减数,形成一个有向图: 由题可得(b−a) + (c−b) <= k1+k2,c−a<=k1+k2.比较k1+k2与k3,其中较小者就是c−a的最大值.由此我们可以得知求差的最大值,即上限被约束,此时我

poj 1201 Intervals【差分约束+spfa】

设s为前缀和,首先显然的条件是\[ s_{bi}-s_{ai-1}>=c \],然后隐含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \] 然后根据差分约束,就是连边(bi,ai-1,-li),(i-1,i,1),(i,i-1,0) spfa跑最长路最后输出相反数即可,注意n是起点,min是终点,跑最短路(不会有负环) #include<iostream> #include<cstdio> #include<queue> usi

poj1716 Integer Intervals(差分约束)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Integer Intervals Time Limit: 1000MS   Memory Limit: 10000K Description An integer interval [a,b], a < b, is a set of all consecutive integers beginning with a and ending with b. Write a prog

codevs 1183 泥泞的道路 (二分+SPFA+差分约束)

/* 二分答案(注意精度) 对于每一个答案 有(s1+s2+s3...)/(t1+t2+t3...)>=ans 时符合条件 这时ans有变大的空间 对于上述不等式如果枚举每一条路显得太暴力 化简一下变成 :s1-t1*ans+s2-t2*ans+s3-t3*ans...>=0 差分约束跑最长路 如果dis[n]>0 或者有正环 (开始这个忘掉了)ans就合法 */ #include<iostream> #include<cstdio> #include<cs