POJ1201 区间

题目大意:

给定n个整数区间[ai,bi]和n个整数ci,求一个最小集合Z,满足|Z∩[ai,bi]|>=ci(Z里边在闭区间[ai,bi]的个数不小于ci)。

多组数据:

n(1<=n<=50000)区间的个数

n行:

ai bi ci(0<=ai<=bi<=50000,1<=ci<=bi-ai+1)

_____________________________________________________

这是一道查分约束题目。

Si为0-i中包含在Z中的个数,固有:

Si-Si-1<=1

Si-Si-1>=0

Sbi-Sai-1>=ci

依照上面不等式,变形并建边。

求的Smax-S0>=x,变形为S0-Smax<=-x,所以求max到0的最短路,就是答案的相反数。

_____________________________________________________

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<queue>
 7 using namespace std;
 8 int n,maxd;
 9 struct edge
10 {
11     int u,v,w,next;
12 }e[150010];
13 int head[50010],js=0;
14 int dis[50010];
15 bool inq[50010];
16 int inqt[50010];
17 queue<int>q;
18 void init()
19 {
20     js=0;
21     maxd=0;
22     memset(head,0,sizeof(head));
23 }
24 void addage(int u,int v,int w)
25 {
26     e[++js].u=u;e[js].v=v;e[js].w=w;
27     e[js].next=head[u];head[u]=js;
28 }
29 bool spfa()
30 {
31     memset(inq,0,sizeof(inq));
32     memset(dis,0x7f,sizeof(dis));
33     memset(inqt,0,sizeof(inqt));
34     q.push(maxd+1);
35     inq[maxd+1]=1;
36     inqt[maxd+1]=1;
37     dis[maxd+1]=0;
38     while(!q.empty())
39     {
40         int u=q.front();
41         q.pop();
42         inq[u]=0;
43         for(int i=head[u];i;i=e[i].next)
44         {
45             int v=e[i].v;
46             if(dis[v]>dis[u]+e[i].w)
47             {
48                 dis[v]=dis[u]+e[i].w;
49                 if(!inq[v])
50                 {
51                     inq[v]=1;
52                     inqt[v]++;
53                     q.push(v);
54                     if(inqt[v]>50000)return 0;
55                 }
56             }
57         }
58     }
59     return 1;
60 }
61 int main()
62 {
63     while(scanf("%d",&n)==1)
64     {
65         init();
66         for(int a,b,c,i=1;i<=n;i++)
67         {
68             scanf("%d%d%d",&a,&b,&c);
69             if(b>maxd)maxd=b;
70             addage(b+1,a,-c);
71         }
72
73         for(int i=1;i<=maxd+1;i++)
74         {
75             addage(i-1,i,1);
76             addage(i,i-1,0);
77         }
78         if(spfa())printf("%d\n",-dis[0]);
79     }
80     return 0;
81 }

时间: 2024-10-09 04:13:44

POJ1201 区间的相关文章

poj1201——差分约束,spfa

poj1201——差分约束,spfa Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 22553   Accepted: 8530 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of inte

poj1201 Intervals

http://poj.org/problem?id=1201 s[i]表示[0..i]中选取了几个整数 则可以得到一些不等式 s[a]-s[b-1]>=c  ([a,b]区间至少要选取c个) s[i-1]-s[i]>=-1 s[i]-s[i-1]>=0 然后,使用差分约束系统做 Program poj1201; type cord=record ne,po,da:longint; end; var n,le,lr:longint; head:array[0..50000]of longi

饥饿的牛 线性dp内的区间

饥饿的牛 牛在饲料槽前排好了队.饲料槽依次用1到N(1<=N<=100000)编号.每天晚上,一头幸运的牛根据约翰的规则,吃其中一些槽里的饲料. 约翰提供B个区间的清单.一个区间是一对整数start-end,1<=start<=end<=N,表示一些连续的饲料槽,比如1-3,7-8,3-4等等.牛可以任意选择区间,但是牛选择的区间不能有重叠.当然,牛希望自己能够吃得越多越好.给出一些区间,帮助这只牛找一些区间,使它能吃到最多的东西.在上面的例子中,1-3和3-4是重叠的:聪明

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

[Noi2016]区间

题目描述 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri. 对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度.区间 [li,ri] 的长度定义为 ri?li,即等于它的右端点的值减去左端点的值. 求所有合法方案中最小的花费.如果不存在合法的方案,输出 ?1. 输入输出格式

7620:区间合并

7620:区间合并 总时间限制: 1000ms 内存限制: 65536kB 描述 给定 n 个闭区间 [ai; bi],其中i=1,2,...,n.任意两个相邻或相交的闭区间可以合并为一个闭区间.例如,[1;2] 和 [2;3] 可以合并为 [1;3],[1;3] 和 [2;4] 可以合并为 [1;4],但是[1;2] 和 [3;4] 不可以合并. 我们的任务是判断这些区间是否可以最终合并为一个闭区间,如果可以,将这个闭区间输出,否则输出no. 输入 第一行为一个整数n,3 ≤ n ≤ 5000

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

HDU 1754 I Hate It(线段树之单点更新,区间最值)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 70863    Accepted Submission(s): 27424 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的

dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:655   Accepted:54 [Submit][Status][Discuss] Description 已知一个长度为 n 的数组 a[1],a[2],-,a[n],我们进行 q 次询问,每次询问区间 a[l],a[l+1],-,a[r?1],a[r] ,数字从小到大