Hdu1384-Intervals(差分约束)

Problem 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 endpoints 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 <= 50 000) - 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 <= 50 000 and 1 <= ci <= bi - ai + 1.
Process to the end of file.

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

题意:对于每个区间[a,b]至少要有c个元素,问集合里元素的最小个数。

解析:差分约束,用Ti表示区间[0,i-1]有多少个元素在里面,则满足下面的条件

Tb+1-Ta>=c

0<=Ti+1-Ti<=1

则建边(a,b+1,c),(i,i+1,0),(i+1,i,-1) 然后用spfa求得答案。注意这题用vector可能会超时。

代码

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
const
int INF=1e9+7;
const
double eps=1e-7;
const
int maxn=50005;
int
N;
struct
edge
{

    int
u,v,w,next;
    edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){next=-1; }
}
E[maxn*3];
int
head[maxn],dist[maxn];
bool
inq[maxn];
queue<int> que;
int
spfa(int be,int en)
{

    for
(int i=be;i<=en;i++) dist[i]=-INF;
    dist[be]=0;
    memset(inq,false,sizeof(inq));
    while
(!que.empty()) que.pop();
    que.push(be);
    while
(!que.empty())
    {

        int
u=que.front();  que.pop();
        inq[u]=false;
        for
(int i=head[u];i!=-1;i=E[i].next)
        {

            int
v=E[i].v,w=E[i].w;
            if
(dist[v]<dist[u]+w)  //更新
            {

                dist[v]=dist[u]+w;
                if
(!inq[v]){ inq[v]=true; que.push(v); }
            }
        }
    }

    return
dist[en];
}

int
main()
{

    while
(scanf("%d",&N)!=EOF)
    {

        memset(head,-1,sizeof(head));
        int
u,v,w,cnt=0;
        int
minv=INF,maxv=-INF;
        for
(int i=0;i<N;i++)
        {

            scanf("%d%d%d",&u,&v,&w);  //建边(u,v+1,w);
            v++;
            E[++cnt]=edge(u,v,w);
            E[cnt].next=head[u];
            head[u]=cnt;
            minv=min(minv,u);
            maxv=max(maxv,v);
        }

        for
(int i=minv;i<maxv;i++)
        {

            E[++cnt]=edge(i,i+1,0); //建边(i,i+1,0)
            E[cnt].next=head[i];
            head[i]=cnt;
            E[++cnt]=edge(i+1,i,-1); //建边(i+1,i,-1)
            E[cnt].next=head[i+1];
            head[i+1]=cnt;
        }

        printf("%d\n",spfa(minv,maxv));
    }

    return
0;
}

时间: 2024-10-28 22:50:41

Hdu1384-Intervals(差分约束)的相关文章

poj1201/zoj1508/hdu1384 Intervals(差分约束)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Intervals Time Limit: 10 Seconds      Memory Limit: 32768 KB You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: > reads the number of interva

「POJ1201」Intervals - 差分约束

->戳我进原题 *** Intervals Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 30393 Accepted: 11768 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, the

POJ 1201 Intervals 差分约束

http://poj.org/problem?id=1201 TLE了很久,因为用了cin..... 思路和其他差分约束差不多,http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 如果区间[a, b]中至少有c个元素,如果用上面的博客,那么说明xa - xb >= c,但是注意这里是闭区间,xa - xb是不包括b这个点的, 就比如用了[a, b]有c个元素,[b, d]有x个,那么ans = c + x - 1个,

【POJ1716】Integer Intervals——差分约束||贪心

题目大意:给出n个区间,现在要你找出一个点集,使得这n个区间都至少有2个元素在这个点集里面,问这个点集最少有几个点. 解法一:差分约束系统 分析:其实这道题应该说是POJ1201的简化版,不过要注意的一点是,如果你用的是SPFA,那么你的差分约束系统应该为: s[b+1]-s[a]>=2; s[b+1]-s[b]>=0; s[b]-s[b+1]>=1. 为什么下标要全部加上1呢?因为这里的a和b有可能为0,如果按照原来s[a-1]的写法会出现是s[-1]这类数组越界的问题. 代码: #i

poj1201 Intervals——差分约束

题目:http://poj.org/problem?id=1201 差分约束裸题: 设 s[i] 表示到 i 选了数的个数前缀和: 根据题意,可以建立以下三个限制关系: s[bi] >= s[ai-1] + ci ( 1 <= i <= n) s[i] >= s[i-1] + 0 ( 1 <= i <= mx) s[i-1] >= s[i] + (-1) (1 <= i <= mx) 然后求最长路,可以发现其中的 dis 值不会多余增大,也就满足题意要

POJ 2101 Intervals 差分约束

Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27746   Accepted: 10687 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

hdu 1384 Intervals (差分约束)

/* 给你 n 个区间 [Ai, Bi],要求从每一个区间中至少选出 Ci 个数出来组成一个序列 问:满足上面条件的序列的最短长度是多少? 则对于 不等式 f(b)-f(a)>=c,建立 一条 b 到 a 的边 权值为 c,则求的最长路 即为 最小值(集合) 而且有隐含条件:0<=f(a)-f(a-1)<=1 则有边权关系(a,a-1,0)以及(a-1,a,-1); */ /* 一般地,差分约束系统分两类:求最大差和最小差 1.求最大差 建立形如 A-B<=C 的不等式.在原图中加

POJ 1716 Interger Intervals 差分约束(入门题)

题意:给出n个区间[a,b] n,a,b<=1e4,要求找到一个最小集合 使得每个区间至少有两个数在集合中.设d[i]为0~i中有多少个元素在集合中,mn,mx分别为左右端点 则对每个i=1..n都要满足 d[b[i]]-d[a[i]-1]>=2 保证等式有意义,d[i+1]<=d[i]+1 , d[i]<=d[i+1]全部化为小于号 d[a[i]-1]-d[b[i]]<=-2 若答案为ans 则d[mx]-d[mn-1]>=ans 把mx当作源点,求出到mn-1的最短

差分约束小结

ZOJ 2770 Burn the Linked Camp /* ZOJ 2770 Burn the Linked Camp 差分约束 */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int MAXN = 1009; struct Edge { int v, ne, c; } G[MAXN*MAXN]

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