Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 24955 | Accepted: 9497 |
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题意:给n个区间,每个区间上至少要用数字集Z的c[i],问Z最小为多少个
思路:设s[i]表示区间0~i上Z集合中的个数 于是有s[b[i]]-s[a[i-1]]>=c[i]
还有注意每一个位置上要么有Z集合中的数,要么没有,所以还有0<=s[i]-s[i-1]<=1
最后spfa跑一遍最长路即可
注意起点可以是超级源点,也可以是所有区间里面最左边的一个点
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define N 50050
#define INF 999999999
struct Edge
{
int v,next,w;
}edge[N*20];
int cnt,head[N];
int d[N],vis[N];
void init()
{
cnt=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
edge[cnt].v=v;edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int spfa(int s,int t)
{
memset(vis,0,sizeof(vis));
for(int i=s;i<=t;i++)
d[i]=i==s?0:-INF;
vis[s]=1;
queue<int>que;
que.push(s);
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v,w=edge[i].w;
if(d[v]<d[u]+w)
{
d[v]=d[u]+w;
if(!vis[v])
{
vis[v]=1;
que.push(v);
}
}
}
}
return d[t];
}
int main()
{
int n,p,q;
int s,t,w;
while(~scanf("%d",&n))
{
init();
int maxn=-1,minn=INF;
while(n--)
{
scanf("%d %d %d",&s,&t,&w);
addedge(s-1,t,w);
maxn=max(maxn,t);
minn=min(minn,s-1);
}
for(int i=minn+1;i<=maxn;i++)
{
addedge(i,i-1,-1);
addedge(i-1,i,0);
}
printf("%d\n",spfa(minn,maxn));
}
return 0;
}