Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 24152 | Accepted: 9186 |
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.
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
题解:差分约束系统。
之前提到过一道差分约束系统的题,说是用到了树状数组的思想。这道题也是一样的道理。每个点表示的是从开始到当前点中选定的数量。
一般的的差分约束系统的题都是要求 u-v<=x 可以转成u<=v+x的形式,最终通过最短路求解。
而这道题有点不同,他要求的是区间中的数量大于等于某值,即 [x,y] >=z y-(x-1)>=z y>=(x-1)+z 由(x-1)向y连边,然后跑最长路即可。另外主要这道题有一个隐藏条件,就是相邻的两个点记录的值的差应该是大于等于0,小于等于1的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
int point[1000003],v[1000003],c[1000003],next[1000003],tot=0,dis[1000003],maxn=0,can[1000003];
void add(int x,int y,int z)
{
tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;
}
void spfa()
{
queue<int> p; p.push(0); can[0]=1;
while (!p.empty())
{
int now=p.front(); p.pop();
for (int i=point[now];i;i=next[i])
if (dis[v[i]]<dis[now]+c[i])
{
dis[v[i]]=dis[now]+c[i];
if (!can[v[i]])
{
can[v[i]]=1;
p.push(v[i]);
}
}
can[now]=0;
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y+1,z);
maxn=max(maxn,y+1);
}
for (int i=0;i<maxn;i++)
{
add(i,i+1,0);
add(i+1,i,-1);
}
memset(dis,128,sizeof(dis));
dis[0]=0;
spfa();
cout<<dis[maxn]<<endl;
return 0;
}