POJ1201 Intervals(差分約束)
阿新 • • 發佈:2018-03-03
compute 新建 namespace com def desc 滿足 eas spf
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.
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.
思路:
設$S[i]$表示$0-i$這一段區間的前綴和
那麽題目的關系就變成了$S[b_i]-S[a_i]>=c_i$
這是一個很典型的差分約束類問題
題目中要求集合最小,因此轉換為最長路,將所有的式子寫成$B-A>=C$的形式
同時題目中還有一個條件$0<=S[i]-S[i-1]<=1$
因為數據為整數
於是又得到兩個方程
$S\left[ i\right] -S\left[ i-1\right] \geq 0$
$S\left[ i-1\right] -S\left[ i\right] \geq -1$ 但是有個細節:$S[i-1]$不能表示,因此我們需要將所有下標$+1$,此時$S[i]$表示$0 to (i-1)$的前綴和 同時,這個圖一定是聯通的,因此不用新建超級源點
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 28416 | Accepted: 10966 |
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,
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
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 題意:每次給出一段區間$[a_i,b_i]$以及一個數$c_i$,使得在這中間至少有$c_i$個數,求一個最小的集合$Z$,使得集合$Z$滿足上述所有要求,問集合$Z$的大小$S\left[ i-1\right] -S\left[ i\right] \geq -1$ 但是有個細節:$S[i-1]$不能表示,因此我們需要將所有下標$+1$,此時$S[i]$表示$0 to (i-1)$的前綴和 同時,這個圖一定是聯通的,因此不用新建超級源點
#include<cstdio> #include<queue> #include<cstring> #define INF 1e8+10 using namespace std; const int MAXN=1e6+10; #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++) char buf[MAXN],*p1=buf,*p2=buf; inline int read() { char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } struct node { int u,v,w,nxt; }edge[MAXN]; int head[MAXN],num=1; int maxx=-INF,minn=INF; int dis[MAXN],vis[MAXN]; inline void AddEdge(int x,int y,int z) { edge[num].u=x; edge[num].v=y; edge[num].w=z; edge[num].nxt=head[x]; head[x]=num++; } int SPFA() { queue<int>q; memset(dis,-0xf,sizeof(dis)); dis[minn]=0;q.push(minn); while(q.size()!=0) { int p=q.front();q.pop(); vis[p]=0; for(int i=head[p];i!=-1;i=edge[i].nxt) { if(dis[edge[i].v]<dis[p]+edge[i].w) { dis[edge[i].v]=dis[p]+edge[i].w; if(vis[edge[i].v]==0) vis[edge[i].v]=1,q.push(edge[i].v); } } } printf("%d",dis[maxx]); } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #else #endif memset(head,-1,sizeof(head)); int N=read(); for(int i=1;i<=N;i++) { int x=read(),y=read(),z=read(); AddEdge(x,y+1,z); maxx=max(y+1,maxx); minn=min(x,minn); } for(int i=minn;i<=maxx-1;i++) { AddEdge(i+1,i,-1); AddEdge(i,i+1,0); } SPFA(); return 0; }
POJ1201 Intervals(差分約束)