POJ 1384 Intervals (线性差分约束,根据不等式建图,然后跑spfa)

传送门:

http://acm.hdu.edu.cn/showproblem.php?pid=1384

Intervals

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4841    Accepted Submission(s): 1815

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

Author

1384

Recommend

Eddy   |   We have carefully selected several similar problems for you:  1529 1531 1548 1534 1317

题目意思:

给出 n 个区间,每个区间有个权值 Ci,最终找出一个最少的数字的集合,使得满足每个区间中至少包含 Ci 个数。

给你几组的a,b,c

从区间a到b(闭区间)选择至少c个数放入集合

要求集合中的数字最少,问你最少多少个数字

分析:

f(a)表示从0到a有f(a)个数放入集合

那么a,b,c根据不等式建立边

f(b)-f(a-1)>=c

这个不等式的意思是:从区间a,b里面选择至少c个数加入集合

隐藏的不等式:0<=f(i)-f(i-1)<=1

变形一下:

f(i)-f(i-1)>=0

f(i-1)-f(i)>=-1

根据这三个不等式建立边

找到区间在最左端:minn

找到区间的最右端:maxx

所以这样建立边的话,跑最短路的时候

起点应该是max,终点是min-1

f(max)-f(min-1)>=x

x就是我们需要的结果

code:

#include <iostream>
#include <cstdio>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<memory>
#include<queue>
#include<vector>
using namespace std;
#define max_v 50010
#define INF 9999999
int tot;
int head[max_v];
int vis[max_v];
int dis[max_v];
int minn,maxx;
struct node
{
    int u,v,val;
    int next;
}Edge[max_v<<2];
void addEdge(int u,int v,int val)
{
    Edge[tot].u=u;
    Edge[tot].v=v;
    Edge[tot].val=val;
    Edge[tot].next=head[u];
    head[u]=tot++;
}
void spfa()
{
    for(int i=minn-1;i<=maxx;i++)
        dis[i]=-INF;
    queue<int> q;
    dis[maxx]=0;
    vis[maxx]=1;
    q.push(maxx);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=Edge[i].next)
        {
            int v=Edge[i].v;
            if(dis[v]<dis[u]+Edge[i].val)
            {
                dis[v]=dis[u]+Edge[i].val;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    printf("%d\n",dis[minn-1]);
    return ;
}
int main()
{
    int n,a,b,c;
    while(~scanf("%d",&n))
    {
        tot=0;
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        maxx=0;
        minn=INF;
        for(int i=0;i<n;i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            a++;
            b++;
            minn=min(minn,a);
            maxx=max(maxx,b);
            addEdge(b,a-1,c);
        }
        for(int i=minn;i<=maxx;i++)
        {
            addEdge(i,i-1,0);
            addEdge(i-1,i,-1);
        }
        spfa();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/yinbiao/p/9445855.html

时间: 2024-10-17 17:58:55

POJ 1384 Intervals (线性差分约束,根据不等式建图,然后跑spfa)的相关文章

POJ 1201 Intervals(差分约束 区间约束模版)

关于差分约束详情可阅读:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 题意: 给定n个区间[L,R], 每个区间至少放w个球, 问最后整个区间最少要放多少个球. 分析: 假设d[i] 是 [1,i] 至少有多少个点被选中, 特殊地, d[0] = 0. 每个区间的描述可以转化为d[R] - d[L-1] >= w.(因为d[L]也要选中, 左闭右闭区间, 所以要减d[L-1])因为d[i]描述了一个求和函数,所

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

POJ 1201 Intervals(差分约束)

[题目链接] http://poj.org/problem?id=1201 [题目大意] 告诉你一个区间至少要选定的数字的个数,给出n个区间的需求 问最少选取几个数字可以满足所有的需求 [题解] 对于区间[a,b]建立不等式Sb+1-Sa>=c,最后要求最小化Smax, 结合基础条件Si+1-Si>=0,Si-Si+1>=-1,构造差分约束系统求最长路就是答案. [代码] #include <cstdio> #include <algorithm> #includ

POJ 1201 Intervals(差分约束+spfa 求最长路径)

题目链接:http://poj.org/problem?id=1201 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, com

HDU 1384 Intervals (差分约束)

Sample Input 5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1 Sample Output 6 题意:给你n个数u,v,w:要求在[u,v]区间至少取w个数(整数),求最少要取多少个数. S[v+1] - S[u] >= w, S[i+1] - S[i] >=0&&<=1,S[i] - S[i+1] <=-1. 在u,v+1之间建一条边,跑一遍SPFA即可. #include <iostream> #include <

POJ 1201 Intervals (差分约束,最短路)

题意:假设有一个自然数区间[0,50000],要从中挑出一些自然数出来,但是现在不知道整个区间究竟要挑多少个出来,只知道一部分闭区间[a,b]内至少要挑多少个,所知道的有n个闭区间.问至少要挑出多少个? 思路: 对于所给的区间 cnt[b-a]>=k这可以保证了该区间内个数不少于k.但是由于两边都是闭区间,所以要变cnt[b-(a-1)]>=k,表示b到a之间的个数.也就是说,转成式子是b-(a-1)>=k,变换一下为(a-1)-b<=-k,就满足常见的式子b-a<=k啦,可

poj 3169 Layout(差分约束)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6549   Accepted: 3168 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

POJ 1436 Horizontally Visible Segments(线段树建图+枚举)

题目连接:http://poj.org/problem?id=1436 题意:给一些线段,每个线段有三个值y1, y2, x代表起点为(x, y1),终点为(x, y2)的线段.当从一个线段可以作水平线到另一个线段并且不穿过其他线段时,就称这两个线段时水平可见的.当三个线段可以两两水平可见,就称为形成一个线段三角.问:在这些线段中有多少个这样的线段三角? 分析:可以把每条线段看做是一个点,如果它和其他线段是水平可见的,就将这两个点相连,由于是无向图,就是你能看到我,我也能看到你,所以需要连接两次