LG3275 【[SCOI2011]糖果】
前言
我对差分约束有我个人独特的看法,写这题解既是与大家分享,又算作我对差分约束系统的总结。
浅谈差分约束
对于一些给出形如\(x_i-x_j\leq a\)不等式(差分约束)组,求\(x_t-x_s\)的最大值问题,我们考虑把这些式子移项,变成\(x_i\leq x_j+a\)的形式。我们知道该问题存在解则所有的不等式都应该得到满足。而所有的\(x_i\leq x_j+a\)都得到满足的要求正好与最短路算法中最终结果算出来后的性质\(dis_i\leq dis_j+w_{i,j}\)类似,所以联想到可以用最短路来求解该方程组问题,即把\(\{x_n\}\)当做\(V\),对每个不等式建边\((j,i,a)\),设\(x_s=0\),跑最短路后,\(x_t\)即为最大值(因为xs=0了)。下证方法的正确性,先假设问题有解。
- 必要性 算出最短路后根据最短路的性质那么所有的不等式都应该被满足,说明答案是正确的。
- 充分性 根据最短路算法的过程\(x_i\)都被它的限制牢牢控制住,且有一个最严格的限制使得\(x_i\)恰好满足它,那么不可能存在比最短路结果更优的解,说明答案是最优的。
综上,算法正确。(谁看出了问题请联系我。)
无解的情况为图中有负环,对应到原问题中就是一个数比它自己大(小)。
分析此题
每个要求就是个差分约束,然后移项令路权为正,发现都是形如\(b\geq a+1\)的形式,与最长路的结果性质类似,故建立最长路模型,用Bellman-Ford(或者LPFA)求解。对小朋友的要求建模:
- a比b多:\(a>b \rightarrow a\geq b+1\)
- a不少于b:\(a \geq b \rightarrow a \geq b+0\)
- a跟b一样:\(a = b \rightarrow a \geq b+0 \& b \geq a+0\)
其余的都是对偶情况。考虑\(x_i>0 \rightarrow x_i\geq x_0+1\)用0节点向1-n连权为1的边,表示每个小朋友都要分到糖,将dis[0]
设为0,这样对0节点的差分就是每个小朋友应得的点数。
然后注意无解的情况,最长路无解即有正环。另外输入的时候特判一下约束是否是“a大于a自己”这种类型的,直接输出-1,可以提高程序效率。
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#define rg register
#pragma GCC optimize ("O0")
using namespace std;
typedef long long ll;
const int INF=0x7fffffff;
template<class T> inline T read(T&x){
T data=0;
int w=1;
char ch=getchar();
while(ch!='-'&&!isdigit(ch))
ch=getchar();
if(ch=='-')
w=-1,ch=getchar();
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
const int MAXN=1e5+7;
int n,m;
struct Edge
{
int to,nx,w;
}E[MAXN*3]; // 0连边还要O(n)空间
int head[MAXN],ecnt;
inline void addedge(int x,int y,int w)
{
E[++ecnt].to=y,E[ecnt].w=w;
E[ecnt].nx=head[x],head[x]=ecnt;
}
int num[MAXN],dis[MAXN];
bool inq[MAXN];
queue<int>Q;
inline bool SPFA()
{
memset(dis,-1,sizeof(dis));
dis[0]=0;
Q.push(0);
inq[0]=1;
num[0]=1;
while(!Q.empty())
{
int x=Q.front();
Q.pop();
inq[x]=0;
for(rg int i=head[x];i;i=E[i].nx)
{
int y=E[i].to;
if(dis[y]<dis[x]+E[i].w)
{
dis[y]=dis[x]+E[i].w;
if(!inq[y])
{
if(++num[y]>=n) // 一个点最多被松弛n-1次,入队n-1次
return 0;
Q.push(y);
inq[y]=1;
}
}
}
}
return 1;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);read(m);
for(rg int i=1;i<=m;++i)
{
int x,a,b;
read(x);read(a);read(b);
if(x==1)
{
addedge(a,b,0);
addedge(b,a,0);
}
else if(x==2)
{
if(a==b)
{
printf("-1");
return 0;
}
addedge(a,b,1);
}
else if(x==3)
{
addedge(b,a,0);
}
else if(x==4)
{
if(a==b)
{
printf("-1");
return 0;
}
addedge(b,a,1);
}
else if(x==5)
{
addedge(a,b,0);
}
}
for(rg int i=n;i>=1;--i)
addedge(0,i,1);
// cerr<<"build end"<<endl;
if(!SPFA())
printf("-1");
else
{
ll ans=0;
for(rg int i=1;i<=n;++i)
ans+=dis[i];
printf("%lld",ans);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
Hint
ans
要开long long
,0节点向1-n连边要逆序,因为根据讨论
这个题原数据有一个点是一个十万的链
可以卡掉SPFA。
LG3275 【[SCOI2011]糖果】的更多相关文章
- bzoj2330: [SCOI2011]糖果
2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MB Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友 ...
- BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】
2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5395 Solved: 1750[Submit][Status ...
- bzoj 2330 [SCOI2011]糖果(差分约束系统)
2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3574 Solved: 1077[Submit][Status ...
- BZOJ 2330: [SCOI2011]糖果( 差分约束 )
坑爹...要求最小值要转成最长路来做.... 小于关系要转化一下 , A < B -> A <= B - 1 ------------------------------------ ...
- [luogu P3275] [SCOI2011]糖果
[luogu P3275] [SCOI2011]糖果 题目描述 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些 ...
- P3275 [SCOI2011]糖果 && 差分约束(二)
学习完了差分约束是否有解, 现在我们学习求解最大解和最小解 首先我们回想一下是否有解的求解过程, 不难发现最后跑出来任意两点的最短路关系即为这两元素的最短路关系. 即: 最后的最短路蕴含了所有元素之间 ...
- [Luogu 3275] SCOI2011 糖果
[Luogu 3275] SCOI2011 糖果 第一道差分约束.感谢 AZe. 我的理解是根据一些不等关系建一个图,在图上边跑一个最长路(有时候是最短路). 因为可能存在负环,所以必须用 SPFA! ...
- BZOJ 2330 SCOI2011糖果 差分约束
2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2819 Solved: 820 题目连接 http://www ...
- BZOJ2330 SCOI2011 糖果 【差分约束】
BZOJ2330 SCOI2011 糖果 Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一 ...
- 【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA
[bzoj2330]: [SCOI2011]糖果 恩..就是裸的差分约束.. x=1 -> (A,B,0) (B,A,0) x=2 -> (A,B,1) [这个情况加个A==B无解的要特 ...
随机推荐
- sqlalchemy(一)常用连接参数及包
简介: 本文默认你已经有了一定的数据库基础.我们不喜欢写原生SQL语句,那个写着费劲,日常开发时候,我们怎么CRUD数据库呢?一般使用ORM,对象关系映射(英语:Object Relational M ...
- MySQL 占用cpu 100%
目前的线上数据库,分为主从两个库,从库用来做比较耗时的数据统计分析. 今天top了一下从库服务器,发现mysqld 在很长一段时间都占用105% cpu,一开始以为是从库在处理主库的binlog. 两 ...
- TreeMap - 源代码学习笔记
TreeMap 实现了 NavigableMap 接口,而NavigableMap 接口继承于 SortedMap接口. 所有本文还会记录 SortedMap 和 NavigableMap 的阅读笔记 ...
- 深入理解java虚拟机---Class文件(二十)
无符号数.表 当实现了不同语言的编译器,比如jython,jruby等等,那么就可以利用这些语言编写代码,通过各自的编译器编译成符合jvm规范的字节码文件,就可以利用jvm来执行了. Class文件在 ...
- 深入理解java虚拟机---虚拟机工具jstat(十七)
jstack---没什么用 jstack用于生成java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因 ...
- 5.2 C++重载操作符的优先级
参考:http://www.weixueyuan.net/view/6380.html 总结: 重载操作符不能改变操作符的优先级和语法特性. 重载操作符不能改变操作符的优先级和语法特性.例如上一节复数 ...
- 201621123001 《Java程序设计》第7周学习总结
1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 掌握了NetBeans基本使用方法 掌握布局管理器基本概念 尝试了自己在界面布置组件 网格组布 ...
- redis 解析配置文件
在redis安装文件夹里面有redis.conf,查看配置. 一:基础配置介绍 1.units(单位) --这里可以看到 1k和1kb是不一样的, units 这里单位是不区分大小写的,are al ...
- AssetBundle打包详解
Unity5.x AssetBundle打包详解 在网上查看了很多资料,想详细搞清楚AssetBundle的原理.以实现符合项目需求的打包工具和加载逻辑 1. AssetBundle是什么? Asse ...
- java基础学习之抽象类
以下内容是自己学习后的一个备忘笔记,理解上肯定有很多问题,望有耐心的大神能给予指点,谢谢 定义:抽象是对事物的一个模糊定义,它主要对那些有共性功能但具体实现不同的对象进行抽象,提高代码的复用性和简洁性 ...