poj 1201(差分约束)

Intervals

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 24948   Accepted: 9491

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

差分约束的区间约束问题。

题意:给定n(n <= 50000)个整点闭区间和这个区间中至少有多少整点需要被选中,每个区间的范围为[ai, bi],并且至少有ci个点需要被选中,其中0 <= ai <= bi <= 50000,问[0, 50000]至少需要有多少点被选中。

题解:这个题的话是典型的差分约束问题,s[i]代表 [0,i]区间内有多少被选中,所以d[i] - d[j-1] >= w ,但是由于 j是从 0 开始,所以下标要+1,还有就是对于某个区间 [i,i],0<=s[i+1]-s[i]<=1,这样的话根据约束条件就可以求出s->t的最长路即是最后的结果。

差分约束不等式的标准化:

如果给出的不等式有"<="也有">=",又该如何解决呢?很明显,首先需要关注最后的问题是什么,如果需要求的是两个变量差的最大值,那么需 要将所有不等式转变成"<="的形式,建图后求最短路;相反,如果需要求的是两个变量差的最小值,那么需要将所有不等式转化成">=",建图 后求最长路。

如果有形如:A - B = c 这样的等式呢?我们可以将它转化成以下两个不等式:

A - B >= c      (1)

A - B <= c      (2)

再通过上面的方法将其中一种不等号反向,建图即可。

最后,如果这些变量都是整数域上的,那么遇到A - B < c这样的不带等号的不等式,我们需要将它转化成"<="或者">="的形式,即 A - B <= c - 1。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const int INF = 999999999;
const int N = 160000;
const int M = 50005;
int n;
struct Edge{
    int v,w,next;
}edge[N];
int head[M];
int tot;
void init(){
    memset(head,-1,sizeof(head));
    tot = 0;
}
void addEdge(int u,int v,int w,int &k){
    edge[k].v = v,edge[k].w = w,edge[k].next = head[u],head[u] = k++;
}
bool vis[M];
int low[M];
int spfa(int s,int t){
    for(int i=s;i<=t;i++){
        vis[i] = false;
        low[i] = -INF;      ///求最长路初始值应该是 -INF
    }
    queue<int> q;
    low[s] = 0;
    q.push(s);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(int k=head[u];k!=-1;k=edge[k].next){
            int v = edge[k].v,w = edge[k].w;
            if(low[v]<low[u]+w){
                low[v] = low[u]+w;
                if(!vis[v]){
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
    return low[t]-low[s];
}
int main(){
    while(scanf("%d",&n)!=EOF){
        init();
        int MIN = INF,MAX = -1;
        for(int i=1;i<=n;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            MAX = max(MAX,v+1);
            MIN = min(MIN,u);
            addEdge(u,v+1,w,tot);
        }
       // printf("%d %d\n",MIN,MAX);
        for(int i=MIN;i<MAX;i++){
            addEdge(i,i+1,0,tot);
            addEdge(i+1,i,-1,tot);
        }
        printf("%d\n",spfa(MIN,MAX));
    }
    return 0;
}
时间: 2024-08-29 01:50:27

poj 1201(差分约束)的相关文章

poj 1201 差分约束+spfa

非常经典的差分约束系统的建模.求最小值需要转化为求最长路. 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int INF = 99999999; 8 const int N = 50002; 9 const int M = 200000; 10 int head[N];

poj 3169 差分约束

3169 差分约束的是满足多组形如xi-yj<=bk{i,j<n k<m}不等式极值问题,可以转化为单源最短路来求. 在最短路中 d[v]<=d[u]+w(u,v) 可以看出跟上面的不等式很像 通常有两种一种是求满足所有不等式的最大值,还有是最小值. 这篇博客可以参考一下 分析: 题目给出了两种不等式  d[u]+dl >=d[v]       d[u]+dd<=d[v]  要求的是最大值,也就是最短路 对于d[u]+dl>=d[v] 建边(u,vdl) 对于d[

POJ 3159[差分约束]

题目链接:[http://poj.org/problem?id=3159] 题意:有N个小朋友,编号为1-N,每个小朋友将分的一些糖果,给出一些关系A.B.C .表示B最多比A多C个,然后问你盆友1和盆友N的糖果数最大差多少.保证有解. 题解:差分约束求最短距离:DIJ+对优化||SPAF+栈优化 #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using name

POJ 1364[差分约束]

题目链接:[http://poj.org/problem?id=1364] 晕死了.但是也长知识了 题意:一个长度为n的序列:a[1].a[2].a[3]...a[n],然后给你一些约束条件:si.ni.gt||lt.ki表示:a[si].a[si+1]....a[si+ni]<or>ki,问你满足这些约束条件,字符串是否存在.存在输出:lamentable kingdom,否则输出:successful conspiracy 题解:对序列求前缀和,将约束条件改为:sum[si+ni]-sum

poj 1364差分约束

King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10206   Accepted: 3777 Description Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound kin

Intervals poj 1201 差分约束系统

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

poj 3159 差分约束+spfa

由于此题数据特殊,队列优化的spfa会超时,可以改成用栈来优化. 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int INF = 9999999; 8 const int N = 30001; 9 const int M = 150000; 10 int head[N

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 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个,