Intervals
Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu
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.
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
Source
Southwestern Europe 2002
一开始每条边限制为 c ,但是还有隐含条件!!!
每个点有取或不取两种情况,那么 0<= s[i] - s[i-1] <=1 , 分别两边再求最短路或最长路即可。。(按照建模方式来。。。)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=50005;
struct Edge
{
int to,next;
int val;
}edge[maxn<<2];
int head[maxn];
int maxedge;
inline void addedge(int u,int v,int c)
{
edge[++maxedge]=(Edge){v,head[u],c};
head[u]=maxedge;
}
int n,minnode=INF,maxnode=-INF;
inline void init()
{
scanf("%d",&n);
memset(head,-1,sizeof(head));
maxedge=-1;
for(int i=1;i<=n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(b+1,a,-c);//dis[i] representing Node i-1
minnode=min(minnode,a);
maxnode=max(maxnode,b+1);
}
for(int i=minnode;i<maxnode;i++)
{
addedge(i,i+1,1);
addedge(i+1,i,0);
}
}
int dis[maxn];
bool inque[maxn];
inline int spfa(int S,int T)
{
deque <int> que;
memset(dis,0x3f,sizeof(dis));
dis[S]=0;inque[S]=true;
que.push_back(S);
int sum=0,tot=1;
while(!que.empty())
{
int u=que.front();que.pop_front();
if(dis[u]*tot>sum) { que.push_back(u);continue; }
else inque[u]=false,tot--,sum-=dis[u];
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].val)
{
dis[v]=dis[u]+edge[i].val;
if(inque[v]) continue;
inque[v]=true;tot++,sum+=dis[v];
if(!que.empty())
if(dis[v]<dis[que.front()]) que.push_front(v);
else que.push_back(v);
else que.push_back(v);
}
}
}
return dis[T];
}
int main()
{
#ifdef Local
freopen("interval.in","r",stdin);
freopen("interval.out","w",stdout);
#endif
init();
cout<<-spfa(maxnode,minnode)<<endl;//shortest path needs to be reversed!
return 0;
}