HDU 1384 Intervals 差分约束
Intervals
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139 Accepted Submission(s): 760
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
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.
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
代码 :
// 差分约束 #include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<queue> using namespace std ; typedef pair< int , int >pii ; #define MAX 50010 vector<pii>qe[MAX]; #define INF 25797524 int d[50010] ; bool vi[MAX] ; //d[t+1]-d[s] >= c,也就是dist[t+1] >= dist[s] + c, //这是求最长路的形式,所以要求最长路 // 看形势 // 如果转化的是 d[s] - d[e] < - w ; 那么 的d[e] > d[s] + w ; // 这求的就是最短路 // 网上看的,用SPFA解差分方程,用最短路径求差分方程的最大解;用最长路径求差分方程的最小解.
void spfa( int Max , int Min ) { int i , j , now ; int u , w ; memset( vi , 0 , sizeof(vi) ) ; queue<int>q ; for( i = Min ; i <= Max ;i++ ) d[i] = -INF ;// 因为求最长路 d[Min] = 0 ; q.push( Min ) ; vi[1] = Min ; while( !q.empty()) { now = q.front( ) ; q.pop( ) ; for( i = 0 ; i < qe[now].size() ; i++) { pii a = qe[now][i] ; u = a.first ; w = a.second ; if( d[u] < w + d[now] ) // 最长路形势 { d[u] = w + d[now] ; if(!vi[u]) { q.push( u ) ; vi[u]= 1 ; } } } vi[now] = 0 ; } } int main() { int i , j , n ,m ; int u , v , w , len, Max = MAX , Min ; while( scanf( "%d" , &n ) != EOF ) { for( i = 0 ; i <= Max ; i++) qe[i].clear() ; Max = 0 ;Min = INF ; for( i = 1 ; i <= n ;i++ ) { scanf( "%d%d%d" , &u , &v , &w ) ; qe[u].push_back( pii( v+1 , w ) ) ; if( v + 1 > Max ) Max = v + 1 ; if( u < Min ) Min = u ; } for( i = Min ; i < Max ; i++) { qe[i+1].push_back(pii( i , -1 )) ; qe[i].push_back( pii( i + 1 , 0 ) ) ; } spfa( Max , Min ) ; printf( "%d\n" ,d[Max] - d[Min] ) ; } }