POJ 1384 Intervals (線性差分約束,根據不等式建圖,然後跑spfa)
阿新 • • 發佈:2018-08-08
seve bottom accepted iostream spf style urn comm scribe
Write a program that:
> reads the number of intervals, their endpoints 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
Process to the end of file.
Author
1384
傳送門:
http://acm.hdu.edu.cn/showproblem.php?pid=1384
Intervals
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4841 Accepted Submission(s): 1815
Write a program that:
> reads the number of intervals, their endpoints 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 <= 50 000) - 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 <= 50 000 and 1 <= ci <= bi - ai + 1.
Process to the end of file.
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
Recommend Eddy | We have carefully selected several similar problems for you: 1529 1531 1548 1534 1317 題目意思: 給出 n 個區間,每個區間有個權值 Ci,最終找出一個最少的數字的集合,使得滿足每個區間中至少包含 Ci 個數。 給你幾組的a,b,c 從區間a到b(閉區間)選擇至少c個數放入集合 要求集合中的數字最少,問你最少多少個數字 分析: f(a)表示從0到a有f(a)個數放入集合 那麽a,b,c根據不等式建立邊 f(b)-f(a-1)>=c 這個不等式的意思是:從區間a,b裏面選擇至少c個數加入集合 隱藏的不等式:0<=f(i)-f(i-1)<=1 變形一下: f(i)-f(i-1)>=0 f(i-1)-f(i)>=-1 根據這三個不等式建立邊 找到區間在最左端:minn 找到區間的最右端:maxx 所以這樣建立邊的話,跑最短路的時候 起點應該是max,終點是min-1 f(max)-f(min-1)>=x x就是我們需要的結果 code:
#include <iostream> #include <cstdio> #include<stdio.h> #include<algorithm> #include<cstring> #include<math.h> #include<memory> #include<queue> #include<vector> using namespace std; #define max_v 50010 #define INF 9999999 int tot; int head[max_v]; int vis[max_v]; int dis[max_v]; int minn,maxx; struct node { int u,v,val; int next; }Edge[max_v<<2]; void addEdge(int u,int v,int val) { Edge[tot].u=u; Edge[tot].v=v; Edge[tot].val=val; Edge[tot].next=head[u]; head[u]=tot++; } void spfa() { for(int i=minn-1;i<=maxx;i++) dis[i]=-INF; queue<int> q; dis[maxx]=0; vis[maxx]=1; q.push(maxx); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=Edge[i].next) { int v=Edge[i].v; if(dis[v]<dis[u]+Edge[i].val) { dis[v]=dis[u]+Edge[i].val; if(!vis[v]) { vis[v]=1; q.push(v); } } } } printf("%d\n",dis[minn-1]); return ; } int main() { int n,a,b,c; while(~scanf("%d",&n)) { tot=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); maxx=0; minn=INF; for(int i=0;i<n;i++) { scanf("%d %d %d",&a,&b,&c); a++; b++; minn=min(minn,a); maxx=max(maxx,b); addEdge(b,a-1,c); } for(int i=minn;i<=maxx;i++) { addEdge(i,i-1,0); addEdge(i-1,i,-1); } spfa(); } return 0; }
POJ 1384 Intervals (線性差分約束,根據不等式建圖,然後跑spfa)