「POJ1201」Intervals - 差分约束
Posted horrigue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「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, 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
思路
典型差分约束题,这个东西着实比较抽象,所以我调了好长时间才过2333。
这个题大概是这样的:
给定 (n) 个闭区间 ([ai,bi](1≤n,0≤ai,bi≤50000)) 和 (n) 个整数 (ci(1≤i≤n))
你需要构造一个整数集合 (Z),使得 (?i∈[1,n]),(Z) 中满足 (ai≤x≤bi) 的整数 (x) 不少于 (ci)个。
求这样的整数集合 (Z) 最少包含多少个数。
设 (s[k]) 表示 (0) 到 (k) 之间最少选出多少个整数。根据题意,有 (s[bi]?s[ai?1]≥ci) 个,这很明显是一个差分约束系统的模型。
不过,我们还要增加一些隐含的条件,才能保证求出的解是有意义的:
1) (s[k]?s[k?1]≥0) (0) 到 (k) 之间选出的书肯定在 (0) 到 (k?1) 内。
2) (s[k]?s[k?1]≤1) 每个数只能被选一次。可变形为 (s[k?1]?s[k]≥?1) 。
代码
#include<cstdio>
#include<cctype>
#include<iostream>
#include<queue>
#include<cstring>
#define rg register
using namespace std;
inline int read(){
rg int f = 0, x = 0;
rg char ch = getchar();
while(!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while( isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
return f? -x: x;
}
const int N = 50010;
const int inf = 0x7f7f7f7f;
int n, head[N], tot, dis[N], minn = inf, maxn = -inf;
bool vis[N];
struct edge{
int to, nxt, w;
}e[N << 4];
inline void add(rg int u, rg int v, rg int w){
e[++tot].nxt = head[u];
e[tot].to = v;
e[tot].w = w;
head[u] = tot;
}
inline void spfa(){
queue<int > q;
for(rg int i = minn; i <= maxn; ++i) dis[i] = -inf;
dis[minn] = 0;
q.push(minn);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(rg int i = head[u]; i; i = e[i].nxt){
int v = e[i].to;
if(dis[v] < dis[u] + e[i].w){
dis[v] = dis[u] + e[i].w;
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
} `
signed main(){
n = read();
for(rg int i = 1; i <= n; ++i){
int a = read(), b = read(), c = read();
add(a - 1, b, c);
minn = min(minn, a - 1);
maxn = max(maxn, b);
}
for(rg int i = minn; i <= maxn; ++i){
add(i - 1, i, 0);
add(i, i - 1, -1);
}
spfa();
printf("%d", dis[maxn]);
return 0;
}
以上是关于「POJ1201」Intervals - 差分约束的主要内容,如果未能解决你的问题,请参考以下文章