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;
}