差分约数
Intervals
差分约束详解 转 https://blog.csdn.net/whereisherofrom/article/details/78922648
他这个一看就懂
Intervals
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 32784 Accepted: 12667
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
间隔
时间限制: 2000MS 内存限制: 65536K
描述
给定n个闭合的整数区间[ai,bi]和n个整数c1,...,cn。
编写一个程序:
从标准输入读取间隔数,它们的终点和整数c1,...,cn,
计算整数集合Z的最小尺寸,它至少具有ci公共元素的间隔[ai, bi],对于每个i = 1,2,...,n,
将答案写入标准输出。
输入
输入的第一行包含整数n(1 <= n <= 50000) - 间隔数。以下n行描述了间隔。输入的第(i + 1)行包含由单个空格分隔的三个整数ai,bi和ci,并且使得0 <= ai <= bi <= 50000并且1 <= ci <= bi-ai + 1。
产量
对于每个i = 1,2,...,n,输出恰好包含一个等于集合Z的最小尺寸的整数,该集合Z至少与区间[ai,bi]共享ci元素。
样本输入
五
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
样本输出
6
资源
2002年西南欧
> s(b) - s(a - 1) >= c 所以 * (-1)得 s(a - 1) - s(b) <= -c 这是条件之一 w(b , a - 1) = -c
> 根据题目s(i) - s(i - 1) >= 0 所以 s(i - 1) - s(i) <= 0 条件二 w(i , i - 1) = 0
> 每个位置上至多有一个元素 s(i ) - s(i - 1) <= 1 条件三 w(i - 1 , i ) = 1
> 然后题目的意思就是让求s(to) - s(from - 1) >= w , 最少就是w , 乘以-1 s(from - 1) - s(to) <= -w
> 为了避免from - 1 < 0 所以在建图的时候全部 a++ , b ++ 也就是将所有的区间向右挪一位
#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <cstring>
//#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std;
const int N = 1e6 + 10 ;
int e[N * 2] , ne[N * 2] , h[N * 2] , idx , w[N * 2] , dis[N] , vis[N] , n , out[N];
bool st[N] ;
void add(int a , int b , int c)
{
a ++ , b ++ ;
e[idx] = b , w[idx] = c , ne[idx] = h[a] , h[a] = idx ++ ;
}
queue<int> q ;
void SPFA(int from)
{
for(int i = 0;i <= N;i ++) dis[i] = 0x3f3f3f3f ;
q.push(from) ;
memset(st , false , sizeof st) ;
dis[from] = 0 ;
st[from] = true ;
int flag = 0 ;
while(q.size())
{
int t = q.front() ;
q.pop() ;
st[t] = false ;
for(int i = h[t] ;i != -1 ;i = ne[i])
{
// cout << " -1 " << endl ;
int j = e[i] ;
if(dis[j] > dis[t] + w[i])
{
dis[j] = dis[t] + w[i] ;
if(!st[j])
{
st[j] = true ;
q.push(j) ;
}
}
}
}
return ;
}
int main()
{
int n1 , n2 ;
while(~scanf("%d",&n))
{
idx = 0 ;
int a ,b , c ;
int from = 0x3f3f3f3f , to = 0 ;
memset(h , -1 , sizeof h);
for(int i = 1;i <= n ;i ++)
{
scanf("%d%d%d",&a, &b, &c) ;
add(b , a - 1, -c) ;
if(from > a) from = a ;
if(b > to) to = b ;
}
// cout << from << " " << to << endl ;
for(int i = from ;i <= to ;i ++)
add(i - 1 , i , 1) , add(i , i - 1 , 0) ;
SPFA(to + 1) ;
printf("%d\n" , -dis[from]);
}
return 0;
}