poj 1201

差分约数

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;
} 
posted @ 2019-08-12 16:47  spnooyseed  阅读(116)  评论(0编辑  收藏  举报