Intervals
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 113 Accepted Submission(s) : 43
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
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
Author
1384
//根据x轴上各点关系建图 -> 差分约束系统 #include <bits/stdc++.h> using namespace std; const int maxn = 50005; const int inf = 1e9; int d[maxn]; int u[3*maxn], v[3*maxn], w[3*maxn], nx[3*maxn], fr[3*maxn]; //一点连接多条边 int T; void add ( int a, int b, int s ) //邻接表建图 { u[T] = a; v[T] = b; w[T] = s; nx[T] = fr[a]; fr[a] = T; T++; } //建边时>= -> 求最长路 void spfa ( int Min, int Max ) //带负权边 { bool vis[maxn]; //是否在队列中 for ( int i = Min; i <= Max; i++ ) { d[i] = -inf; vis[i] = 0; //初始化为极小值 } d[Min] = 0; queue<int>q; q.push ( Min ); vis[Min] = 1; while ( !q.empty() ) { int &t = q.front(); q.pop(); vis[t] = 0; for ( int i = fr[t]; i != -1; i = nx[i] ) if ( d[v[i]] < d[t] + w[i] ) { //更新最长路 d[v[i]] = d[t] + w[i]; if ( !vis[v[i]] ) { q.push ( v[i] ); vis[v[i]] = 1; } } } } int main() { int m; while ( ~scanf ( "%d", &m ) ) { T = 0; memset ( fr, -1, sizeof ( fr ) ); int Min = inf, Max = -inf; while ( m-- ) { int a, b, s; scanf ( "%d%d%d", &a, &b, &s ); add ( a - 1, b, s ); Min = min ( Min, a - 1 ); Max = max ( Max, b ); } for ( int i = Min; i <= Max; i++ ) add ( i, i + 1, 0 ); //相邻两点从左向右 for ( int i = Min; i <= Max; i++ ) add ( i + 1, i, -1 ); //相邻两点从右到左 spfa ( Min, Max ); printf ( "%d\n", d[Max] ); } return 0; }