ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

差分约束

2021-08-14 19:03:48  阅读:196  来源: 互联网

标签:cnt int memset 差分 约束 负环 sizeof


前言

这个算是鸽了很久都没去学的算法。然后模拟赛考出来(我又不会并查集做法),所以在改题之前,还得先完成一下前置知识。

差分约束的前置知识

<Ⅰ>\(Spfa\)判断负环

【模板】负环

用\(Spfa\)判断入队次数是否\(≥n\),如果是,说明有负环。感性理解一下,一个图上如果有负环,它会一直绕着负环跑,然后越来越小,越来越小……

\(code\):

#include<bits/stdc++.h>
using namespace std;
const int N=2e3+105,M=6e3+105;
int n,m,h[N],nex[M],to[M],v[M],cnt,d[N],tot[N],T,x,y,z;
bool f[N];//v已经有了 
inline void add(int x,int y,int z){
	to[++cnt]=y;v[cnt]=z;
	nex[cnt]=h[x];h[x]=cnt;
}
bool spfa(){
	memset(f,0,sizeof(f));memset(d,0x3f,sizeof(d));memset(tot,0,sizeof(tot));
	queue<int>q;
	d[1]=0;f[1]=1;q.push(1);
	while(!q.empty()){
		int x=q.front();q.pop();f[x]=0;
		for(int i=h[x];i;i=nex[i])
			if(d[to[i]]>d[x]+v[i]){
				d[to[i]]=d[x]+v[i];
				if(!f[to[i]]){
					if(++tot[to[i]]>n) return 1;
					q.push(to[i]);f[to[i]]=1;
				}
			}
	}
	return 0;
}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++){
			scanf("%d%d%d",&x,&y,&z);
			add(x,y,z);if(z>=0)add(y,x,z);
		}
		spfa()?puts("YES"):puts("NO");
		memset(h,0,sizeof(h));cnt=0;
	}
	return 0;
}

<Ⅱ> 定义

差分约束系统

给出\(n\)个变量(\(x_1,x_2,x_3……x_n\)),和 \(m\) 个 约束条件 (粗略理解为不等式,求一些满足约束条件的解。

假设给出一个这样的差分约束系统:
\(x_a-x_b ≤ k_1\)
\(x_a-x_c ≤ k_2\)
\(x_b-x_d ≤ k_3\)
\(x_d-x_c ≤ k_4\)

可以把它写成统一形式: \(x_i≤x_j+k\)

转化成图,大概是这样的:

如果要找\(x_a-x_d\)的最小值,即在图上跑点\(a\)到点\(d\)的最短路。

例题

【模板】差分约束算法

\(code\):


标签:cnt,int,memset,差分,约束,负环,sizeof
来源: https://www.cnblogs.com/Nickle/p/15139081.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有