【POJ 1201】 Intervals(差分約束系統)
阿新 • • 發佈:2017-07-03
sub 代碼 idt ear ces oid std one space
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 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.
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.
【POJ 1201】 Intervals(差分約束系統)
11
1716的升級版 把原本固定的邊權改為不固定。
IntervalsTime Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 23817 | Accepted: 9023 |
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
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
關於差分約束系統,百度各種大牛博客講的都非常具體,簡單說就是通過不等關系建立約束系統圖。然後跑最短路(大於關系則跑最長路)
回到此題,題目要求找出一個最小集合S。滿足對於n個範圍[ai,bi],S中存在ci個及ci個以上不同的點在範圍內
令Zi表示滿足條件的情況下,0~i點至少有多少點在集合內
則Zbi-Zai >= ci
僅僅有這一個條件構造出來的圖可能不是全然連通的,所以須要找一些“隱含條件”
不難發現 對於相鄰的點 0 <= Zi-Z(i-1) <= 1 保證關系符同樣 轉化為
Zi-Z(i-1) >= 0
Z(i-1)-Zi >= -1
用這三個關系,就可以構造差分約束系統,然後SPFA或者Bellman跑一趟最長路(滿足全部條件)
代碼例如以下:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; const int msz = 1e5; const int mod = 1e9+7; const double eps = 1e-8; struct Edge { int v,w,next; }; Edge eg[233333]; int head[50050]; bool vis[50050]; int dis[50050]; int tp,st,en; void Add(int u,int v,int w) { eg[tp].v = v; eg[tp].w = w; eg[tp].next = head[u]; head[u] = tp++; } int SPFA() { memset(vis,0,sizeof(vis)); memset(dis,-INF,sizeof(dis)); queue <int> q; dis[st] = 0; vis[st] = 1; int u,v,w; q.push(st); while(!q.empty()) { u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; i != -1; i = eg[i].next) { v = eg[i].v; w = eg[i].w; if(dis[v] < dis[u]+w) { dis[v] = dis[u]+w; if(!vis[v]) { q.push(v); vis[v] = 1; } } } } return dis[en]; } int main(int argc,char **argv) { int n; int u,v,w; while(~scanf("%d",&n)) { tp = 0; memset(head,-1,sizeof(head)); en = 0,st = INF; while(n--) { scanf("%d%d%d",&u,&v,&w); Add(u,v+1,w); en = max(en,v+1); st = min(st,u); } for(int i = st; i < en; ++i) { Add(i,i+1,0); Add(i+1,i,-1); } printf("%d\n",SPFA()); } return 0; }
【POJ 1201】 Intervals(差分約束系統)