首页 > 其他分享 >差分约束总结

差分约束总结

时间:2023-08-04 13:33:06浏览次数:32  
标签:总结 le int 差分 约束 SPFA now inque dis

差分约束是一个简单的能解一种特殊的 \(n\) 元一次不等式组(或者判断无解)的算法,

其中每个不等式形如 \(x_a-x_b\le c\),\(c\) 是常数。

差分约束利用了最短路的一个性质:

一个有向图跑完最短路后一定满足对于任意一条边 \((x,y,z)\),有 \(dis_y\le dis_x+z\)

这个性质很简单,因为既然有了这样一条边,那么 \(dis_y\) 的范围缩小到最多只能取 \(dis_x+z\),而且以后还可能继续缩小

然后我们把原来的不等式变换一下:\(x_a\le x_b+c\)

发现它与上面的不等式很像!

尝试建图,每个未知数 \(x_i\) 看成是图上的一个节点,

每个约束条件 \(x_i-x_j\le c_k\) 看成一条边

\(x_i\le x_j+c_k\)

于是可以建立一条有向边 \((j,i,c_k)\) (不用死记硬背,理解了这个就知道为什么这样连边了。。。)

然后跑完最短路后即可满足所有的约束条件。

不过从哪个点作为起点呢?实际上每个点都可以作为起点,所以我们建立一个超级原点 \(0\),\(0\) 连向所有点有一条权值为 \(0\) 的边

这样,从节点 \(0\) 开始,每个点都可以走到,也就保证解出了所有的未知数。

注意,此时有额外的边 \((0,i,0)\),说明我们约束所有的未知数 \(x_i\le 0\)

这样跑出来每个 \(dis_i\) 都不是正数...

何时存在无解和无数解?

如果有无法到达的点,则是无数解(这里没有超级原点,因为超级原点是我们为了跑出所有解而人为添加的一个点)

因为这个点无法到达,说明没有边连向它,这就意味着这个点其实是没有约束的,取任意值都满足

如果要判断的话,直接看有没有节点不连边就行

而如果出现了负环,则是无解

因为出现负环意味着根本不存在最短路径,只有更短路径

因为负边权这一存在,迫使我们使用 \(\text{SPFA}\) 这个死去的算法来帮助我们求解

而且很方便的是,它也能帮助我们判负环(无解)。。。

所以别再管什么生与死,用它就对了!

实际上,最短路求出的解一定是 \(x_i\le 0\) 时的最大解

因为我们每个 \(dis_i\) 的范围都是从 \([-\infty,+\infty]\) 缩小(松弛)到 \([-\infty,x]\)

而它最终取的是这个范围内最大的 \(x\)

所以是最大解。

意会一下就可以了((

对应的,如果求 \(x_i\ge 0\) 时的最小解,跑最长路即可

建边时注意一下,最长路满足对于有向边 \((x,y,z)\),\(dis_y\ge dis_x+z\)

所以如果是约束条件 \(x_i\le x_j+c_k\)

\(x_j\ge x_i-c_k\)

所以建边 \((i,j,-c_k)\)

仍然按上面的方法建一个超级源点,则每个 \(x_i\ge 0\)

此时求出的就是正整最小解。

附赠 \(\text{SPFA}\) 最短路 & 判负环

int dis[N], inque[N];
void SPFA(int node) {
    memset(inque, 0, sizeof inque);
    memset(dis, 0x3f, sizeof dis);
    queue<int> q;
    q.push(node);
    dis[node] = 0;
    while (!q.empty()) {
        int now = q.front(); q.pop();
        inque[now] = 0;
        for (int i = h[now]; i; i = a[i].n) {
            int j = a[i].t;
            if (dis[j] > dis[now] + a[i].v) {
                dis[j] = dis[now] + a[i].v;
                if (!inque[j])
                    inque[j] = 1, q.push(j);
            }
        }
    }
}
SPFA(0);

int dis[N], inque[N], cnt[N];
bool SPFA(int node) { // 判负环
    memset(inque, 0, sizeof inque);
    memset(dis, 0x3f, sizeof dis);
    memset(cnt, 0, sizeof cnt);
    queue<int> q;
    q.push(node);
    dis[node] = 0;
    cnt[node]++;
    while (!q.empty()) {
        int now = q.front(); q.pop();
        inque[now] = 0;
        for (int i = h[now]; i; i = a[i].n) {
            int j = a[i].t;
            if (dis[j] > dis[now] + a[i].v) {
                dis[j] = dis[now] + a[i].v;
                cnt[j]++;
                if (cnt[j] == n + 1) return false;
                if (!inque[j])
                    inque[j] = 1, q.push(j);
            }
        }
    }
    return true;
}
puts(SPFA(0) ? "Yes" : "No");

另外拓扑排序好像也可以判...不过不在本文讨论范围内,而且 \(\text{SPFA}\) 适用性更广,具体自己可以百度

标签:总结,le,int,差分,约束,SPFA,now,inque,dis
From: https://www.cnblogs.com/laijinyi/p/17605658.html

相关文章

  • java锁总结
    Java中的锁主要用于保障多并发线程情况下数据的一致性。在多线程编程中为了保障数据的一致性,我们通常需要在使用对象或者方法之前加锁,这时如果有其他线程也需要使用该对象或者该方法,则首先要获得锁,如果某个线程发现锁正在被其他线程使用,就会进入阻塞队列等待锁的释放,直到其他线程......
  • 【技术总结】大数据开发模块化知识体系、学习路线及对应的资料推荐
    〇、概述1、常用网站 2、常用学习路线图极客时间:石墨文档:https://shimo.im/docs/anJWOliiPz0WEjY0/read 大数据课程大纲:https://w.1yb.co/LEAzlvV【即石墨文档】 马士兵教育:https://www.processon.com/view/link/6244466b5653bb072bcd241d#map 尚硅谷:http://www.atguigu.com/......
  • MySql基础及约束
    review#数据库#MySQL数据库数据库基础知识存储数据的仓库,数据是有组织的存储的英文:database,简称DB数据库管理系统是管理数据库的大型软件,英文为DataBaseManagermentSystem简称DBMS关系表数据库SQl是结构化查询语言,用来操作关系型数据库,定义了操作所有关系型数据库......
  • 上位机_WPF系列总结(触发器)
    当达到了出发的条件,执行设定的响应,可以是样式、数据变化、动画等。触发器的类型有:Trigger:检测依赖属性的变化,触发器生效<Window.Resources><Stylex:Key="TestStyle"TargetType="Button"><Style.Triggers><TriggerProperty="IsMou......
  • Capturing Video on iOS iOS拍摄视频的方法总结
    https://www.objc.io/issues/23-video/capturing-video/With processing powerandcamerahardwareimprovingwitheverynewrelease,usingiPhonestocapturevideoisgettingmoreandmoreinteresting.They’resmall,light,andinconspicuous,andthequalityg......
  • 【总结】百家稷学!重点汇总有三AI(教育)服务过的那些企业与学校
    近一年多来我们开始服务B端用户,已经陆续和许多企业和学校进行了长短期的合作,2021年年关将至,下面来简单做一个汇总。阿里云阿里云是我们的第一个客户,合作次数最多,历经时间也最长。自从2019年开始以深度学习模型设计为主题在阿里云开启了3次直播之后,我们后面又与阿里云进行了多次合作......
  • 【总结】超1000页有三AI文档资源领取方法汇总!
    这几年我们平台输出了很多内容,有免费的也有付费的,有图文也有视频,本次对我们所有文档类资源领取方法做一个汇总。有三的书相关资料至今有三已经出版了4本书,分别是《深度学习之图像识别》,《深度学习之模型设计》,《深度学习之人脸图像处理》,《深度学习之摄影图像处理》,介绍如下:一些书......
  • 【总结】从视频到图文,代码实战,有三AI-GAN学习资料汇总!
    GAN无疑是这几年深度学习领域里最酷的技术,不管是理论的研究,还是GAN在图像生成,图像翻译,语音图像等基础领域的应用,都非常的丰富。我们公众号输出过非常多的GAN相关资源,本次做一个简单汇总,我们平台已有的GAN资源包括免费与付费的视频课,知识星球中的GAN模型原理解读专题,公众号的GAN付费......
  • 每日总结8月3日
    今天算是今年第一次下水了吧,水有些凉,跟台风关系不小,但即使是这样游客中游泳的人也不少,在海滩边上的小贩是真的赚钱啊,特意问了一下,1W的摊位费3天就能赚回来,突然对代码的感觉变淡了。下次不能再有这样的想法了,道心不能乱......
  • 主键约束与唯一约束的区别
    数据库中的主键约束和唯一约束是两种不同的约束类型,它们用于确保数据的唯一性。它们之间的区别如下:主键约束(PrimaryKeyConstraint):·主键约束用于定义一个表中的主键。主键是用来唯一标识表中每一行数据的列或列组合。·主键约束要求主键的值在表中是唯一的,并且不能为NULL。......