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
题意:给定X轴上一些区间[ai,bi],其间至少有ci个点,求X轴上至少多少个点。
思路:记得高中是用bellman-ford优化到了NKOJ的第一名。。。。但是差不多搞忘差分约束了。所以现在再来整理总结一下。
此处求最小,显然需要构造T>=S+dist,然后用最长路求。 由于是点段,处理区间最好半开半闭。
#include<queue> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=1500000; const int inf=0x7fffffff; int cnt,n,Max,Min; int Laxt[maxn],Next[maxn],To[maxn],Len[maxn]; int times[maxn],st[maxn],vis[maxn],inq[maxn]; void update() { cnt=0;Min=inf;Max=-inf; memset(Laxt,0,sizeof(Laxt)); memset(vis,0,sizeof(vis)); memset(inq,0,sizeof(inq)); } void add(int u,int v,int d) { Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=d; } bool spfa() { for(int i=Min-1;i<=Max+1;i++) st[i]=-inf; queue<int>q; q.push(Min); st[Min]=0; inq[Min]=1; while(!q.empty()){ int u=q.front(); q.pop(); inq[u]=0; for(int i=Laxt[u];i;i=Next[i]){ int v=To[i]; if(st[v]<st[u]+Len[i]){ st[v]=st[u]+Len[i]; if(!inq[v]){ inq[v]=1; vis[v]++; q.push(v); //if(vis[v]>Max-Min) return false; } } } } return true; } int main() { int a,b,c; while(~scanf("%d",&n)){ update(); for(int i=1;i<=n;i++) { scanf("%d%d%d",&a,&b,&c); a++;b++; if(b>Max) Max=b; if(a-1<Min) Min=a-1; add(a-1,b,c); } for(int i=Min;i<Max;i++) add(i+1,i,-1),add(i,i+1,0); spfa(); printf("%d\n",st[Max]); } return 0; }
原文地址:https://www.cnblogs.com/hua-dong/p/8438131.html