POJ 1201. Intervals

链接

http://poj.org/problem?id=1201

题意

从 $0\sim 50000$ 中选出尽可能少的整数,使每个区间 $[a_i,b_i]$ 内都有至少 $c_i$ 个数被选出

思路

设 $s[k]$ 为 $0\sim k$ 中选出了 $s[k]$ 个数

由题意得:$s_{b_i}-s_{a_i-1}\ge c_i$

又因为:

  • $s_k-s_{k-1}\ge 0$
  • $s_{k-1}-s_k\ge -1$

在 $k-1$ 与 $k$ 之间建立权值为 $0$ 的有向边,$k$ 与 $k-1$ 之间建立权值为 $1$ 的有向边,$a_{i-1}$ 与 $b_{i}$ 之间建立权值为 $c_i$ 的有向边

以 $-1$ 为起点跑最长路,因为 $c_i\le b_i-a_i+1$ ,所以图中不存在正环,一定有解

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <climits>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <bitset>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
//head
const int N=5e4+5;
int n,mx,dist[N];
bool st[N];
VPII G[N];
void spfa() {
for(int i=0;i<=mx;i++) dist[i]=0xc0c0c0c0;
queue<int> q;
q.push(0);
dist[0]=0;
st[0]=true;
while(q.size()) {
int u=q.front();
q.pop();
st[u]=false;
for(int i=0;i<SZ(G[u]);i++) {
int v=G[u][i].FI,w=G[u][i].SE;
if(dist[v]<dist[u]+w) {
dist[v]=dist[u]+w;
if(!st[v]) {
st[v]=true;
q.push(v);
}
}
}
}
printf("%d\n",dist[mx]);
}
int main() {
//freopen("D:/Program Files (x86)/Sublime Text 3/in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
v++;
mx=max(mx,v);
G[u].PB(MP(v,w));
}
for(int i=0;i<mx;i++) G[i].PB(MP(i+1,0));
for(int i=1;i<=mx;i++) G[i].PB(MP(i-1,-1));
spfa();
return 0;
}