区间
给定 n 个区间 [ a i , b i ] 和 n 个 整 数 c i [a_i,b_i]和 n 个整数 c_i [ai,bi]和n个整数ci。
你需要构造一个整数集合 Z,使得∀i∈[1,n],Z 中满足ai≤x≤bi的整数 x 不少于 c i c_i ci个。
求这样的整数集合 Z 最少包含多少个数。
输入格式
第一行包含整数 n。
接下来n行,每行包含三个整数 a i , b i , c i a_i,b_i,c_i ai,bi,ci。
输出格式
输出一个整数表示结果。
数据范围
1
≤
n
≤
50000
1≤n≤50000
1≤n≤50000,
0
≤
a
i
,
b
i
≤
50000
0≤a_i,b_i≤50000
0≤ai,bi≤50000,$
1
≤
c
i
≤
b
i
−
a
i
+
1
1≤c_i≤b_i−a_i+1
1≤ci≤bi−ai+1
输入样例:
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
输出样例:
6
题解:
步骤和上一题一摸一样。
看到最小值就是最长路。
然后就是提取题目中的不等式,我们这里利用前缀和的思想提出了下面几个不等式
s
i
>
=
s
i
−
1
s_i>=s_{i-1}
si>=si−1
s
i
−
s
i
−
1
<
=
1
(
s
i
−
1
>
=
s
i
−
1
)
s_i-s_{i-1}<=1 (s_{i-1}>=s_i-1)
si−si−1<=1(si−1>=si−1)
s
b
>
=
s
a
+
c
s_b>=s_a+c
sb>=sa+c
s数组代表我们第i个数字包含了
s
i
s_i
si个数。
我们做差分约束的时候一定要检查是否我们能通过一个源点到达所有其他的点,这里我们可以发现我们0一定是可以到达所有其他点的。然后我们不等式是否找完了。
这道题一定存在解,所以不存在负环之内的。
#include <bits/stdc++.h>
using namespace std;
const int N=50001,M=3*N;
int ne[M],cnt,head[M],e[M],w[M],dis[N],con[N];
int n;
bool vis[N];
void add(int a,int b,int c)
{
e[cnt]=b,ne[cnt]=head[a],w[cnt]=c,head[a]=cnt++;
}
void spfa()
{
memset(dis,-0x3f3f3f3f,sizeof dis);
memset(vis,0,sizeof vis);
queue<int> q;
dis[0]=0;
q.push(0);
vis[0]=1;
while(!q.empty()){
int u=q.front(); q.pop();
vis[u]=0;
for(int i=head[u];~i;i=ne[i]){
int j=e[i];
if(dis[j]<dis[u]+w[i]){
dis[j]=dis[u]+w[i];
con[j]=con[u]+1;
if(!vis[j]){
q.push(j);
vis[j]=1;
}
}
}
}
}
int main()
{
cin>>n;
memset(head,-1,sizeof head);
for(int i=1;i<=50001;i++){
add(i-1,i,0);
add(i,i-1,-1);
}
for(int i=1;i<=n;++i){
int a,b,c; cin>>a>>b>>c;
a++,b++;
add(a-1,b,c);
}
spfa();
cout<<dis[50001]<<endl;
return 0;
}