专栏文章
P12348 题解
P12348题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miphf9g0
- 此快照首次捕获于
- 2025/12/03 12:03 3 个月前
- 此快照最后确认于
- 2025/12/03 12:03 3 个月前
前言
无内鬼,来点差分约束。
思路
一眼差分约束(或者流),但是流好像不太行,那还是差分约束吧。
注意到 可以转换为 ,这个形式简直就是差分约束板子。
直接暴力将 中的点向 连长度为 的边的话,边数是 复杂度的,又因为 ,所以边数是 复杂度的,总复杂度达到 ,不太能过。
注意到我们可以在每次连边时建立一个中继点,先将 中的点向这个中继点连长度为 的边,再将这个中继点向 连长度为 的边,边数会缩小至 复杂度,即 ,总复杂度为 ,又因为不太能跑的很满,所以可以过。
代码
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
#define fi first
#define se second
#define mkp make_pair
const int N=300024;
int t,n,m,tot;
vector<PII> e[N];
int dis[N],cnt[N];
queue<int> q;
bool spfa(){
while(!q.empty()){
q.pop();
}
for(int i=1;i<=n+m;i++){
q.push(i);
}
while(!q.empty()){
tot++;
int u=q.front();
q.pop();
if(cnt[u]>=m+n+2||tot>10000000){
return 0;
}
cnt[u]++;
for(PII tp:e[u]){
int v=tp.fi,w=tp.se;
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
q.push(v);
}
}
}
return 1;
}
signed main(){
cin>>m>>n;
for(int i=1;i<=m;i++){
int l,r,x,y,w;
cin>>l>>r>>x>>y>>w;
for(int j=l;j<=r;j++){
e[j].push_back(mkp(n+i,-w));
}
for(int j=x;j<=y;j++){
e[n+i].push_back(mkp(j,0));
}
}
if(spfa()){
int mx=dis[1],mn=dis[1];
for(int i=2;i<=n+m;i++){
mx=max(mx,dis[i]);
mn=min(mn,dis[i]);
}
cout<<mx-mn;
}
else{
cout<<"No Solution";
}
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...