BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)
差分约束:
太真实了= = 插个广告:这里有差分约束详(并不)解。
记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值,那么限制\((i,j),k\)就是\(r_i+c_j=k\)。
这就是差分约束裸题了。\(r_i+c_j=k\Rightarrow r_i-(-c_j)\leq k\ \&\&\ -c_j-r_i\leq -k\)。
注意形式是\(x_j-x_i\leq w\)=v=
建边跑最短路判负环即可。
去洛谷复习以前的板子(忘了怎么写了=-=),发现DFS判负环被卡掉了?太棒啦不用背DFS的代码惹。
乖乖写BFS好了。
带权并查集:
发现这题和BZOJ1202是一模一样的= =。因为全是相等关系,其实是十分特殊的差分约束,可以用带权并查集做。
记\(fa[x]\)表示\(x\)所在集合的根节点,\(dis[x]\)表示\(x\)到\(fa[x]\)的实际距离。
所谓距离是指:对于\(r+c=k\),变成\(r-(-c)=k\),即\(r\)比\(-c\)大\(k\),就在\(r\to -c\)之间连距离为\(k\)的边,同时令\(fa[r]=-c\)。
这样对于一个限制\(r,c,k\),如果\(r,c\)不在同一集合就合并(令较大的数的祖先是较小的数)。在并查集\(Find\)过程中顺便维护一下\(dis\)(具体见代码好惹,注意变量赋值顺序)。
如果\(r,c\)在同一集合,就根据\(dis\)差判一下它俩的距离是否等于\(k\)。
就算\(k\)可能是负的这么做也没什么问题。(废话=v=)
差分约束:
//904kb	48ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=2005;
int Enum,H[N],nxt[N],to[N],len[N],dis[N],dgr[N];
bool vis[N],inq[N];
inline int read()
{
	int now=0,f=1;register char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}
inline void AE(int u,int v,int w)
{
	to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
}
bool SPFA(int s,int n)//怎么都直接拿n做总点数的=-= 强迫症表示不行
{
	std::queue<int> q;
	q.push(s), dis[s]=0;
	while(!q.empty())
	{
		int x=q.front(); q.pop();
		inq[x]=0;
		for(int i=H[x],v; i; i=nxt[i])
			if(dis[v=to[i]]>dis[x]+len[i])
			{
				if(++dgr[v]>n) return 1;
				dis[v]=dis[x]+len[i], !inq[v]&&(q.push(v),inq[v]=1);
			}
	}
	return 0;
}
int main()
{
	for(int Ts=read(); Ts--; )
	{
		int n=read(),m=read(),tot=n+m,cnt=0;
		Enum=0, memset(H,0,tot+1<<2), memset(vis,0,tot+1);
		for(int u,v,w,K=read(); K--; )
		{
			u=read(),v=read()+n,w=read();
			AE(v,u,w), AE(u,v,-w);
			if(!vis[u]) vis[u]=1, ++cnt;
			if(!vis[v]) vis[v]=1, ++cnt;
		}
		memset(dis,0x7f,tot+1<<2), memset(dgr,0,tot+1<<2), memset(inq,0,tot+1);
		bool fg=1;
		for(int i=1; i<=tot; ++i)
			if(vis[i]&&dis[i]==dis[0]&&SPFA(i,cnt)) {fg=0; break;}
		puts(fg?"Yes":"No");
	}
	return 0;
}
带权并查集:
//836kb	20ms
#include <cstdio>
#include <cctype>
#include <assert.h>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=2005;
int fa[N],dis[N];
inline int read()
{
	int now=0,f=1;register char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}
int Find(int x)
{
	if(x==fa[x]) return x;
	int t=fa[x];
	fa[x]=Find(t), dis[x]+=dis[t];//!!!
	return fa[x];
}
int main()
{
	for(int Ts=read(); Ts--; )
	{
		const int n=read(),m=read(),tot=n+m;
		for(int i=1; i<=tot; ++i) fa[i]=i, dis[i]=0;
		bool fg=1;
		for(int u,v,w,K=read(); K--; )
		{
			u=read(),v=read()+n,w=read();
			if(!fg) continue;
			int r1=Find(u),r2=Find(v);
			if(r1!=r2) fa[r1]=r2, dis[r1]=dis[v]+w-dis[u];
			else if(dis[u]-dis[v]!=w) fg=0;
		}
		puts(fg?"Yes":"No");
	}
	return 0;
}
												
											BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)的更多相关文章
- POJ——1364King(差分约束SPFA判负环+前向星)
		
King Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11946 Accepted: 4365 Description ...
 - 【bzoj 1202】[HNOI2005] 狡猾的商人(图论--带权并查集+前缀和)
		
题意:一个账本记录了N个月以来的收入情况,现在有一个侦探员不同时间偷看到M段时间内的总收入,问这个账本是否为假账. 解法:带权并查集+前缀和. 判断账本真假是通过之前可算到的答案与当前读入的值是否 ...
 - BZOJ 4500: 矩阵 差分约束
		
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4500 题解: 从行向列建边,代表一个格子a[i][j],对每个顶点的所有操作可以合并在一 ...
 - UVA 515 差分约束 SPFA判负
		
第一次看这个题目,完全不知道怎么做,看起来又像是可以建个图进行搜索,但题目条件就给了你几个不等式,这是怎么个做法...之后google了下才知道还有个差分约束这样的东西,能够把不等式化成图,要求某个点 ...
 - [luoguP1993] 小 K 的农场(差分约束 + spfa 判断负环)
		
传送门 差分约束系统..找负环用spfa就行 ——代码 #include <cstdio> #include <cstring> #include <iostream&g ...
 - 洛谷P3275 [SCOI2011]糖果_差分约束_判负环
		
Code: #include<cstdio> #include<queue> #include<algorithm> using namespace std; co ...
 - 【BZOJ 3376】[Usaco2004 Open]Cube Stacking 方块游戏 带权并查集
		
这道题一开始以为是平衡树结果发现复杂度过不去,然后发现我们一直合并而且只是记录到最低的距离,那么就是带权并查集了,带权并查集的权一般是到根的距离,因为不算根要好打,不过还有一些其他的,具体的具体打. ...
 - Poj 3259 Wormholes(spfa判负环)
		
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 42366 Accepted: 15560 传送门 Descr ...
 - poj 1364 King(线性差分约束+超级源点+spfa判负环)
		
King Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14791 Accepted: 5226 Description ...
 
随机推荐
- 暑假闲着没事第一弹:基于Django的长江大学教务处成绩查询系统
			
本篇文章涉及到的知识点有:Python爬虫,MySQL数据库,html/css/js基础,selenium和phantomjs基础,MVC设计模式,ORM(对象关系映射)框架,django框架(Pyt ...
 - python魔法方法之构造和析构
			
python的类实例化的时候会默认执行该类的构造方法_init_ class Rectangle: def __init__(self,x,y): self.x=x self.y=y def getA ...
 - matlab 加根号
			
text(3,0.5,'z=0.2$$\sqrt{c/h_0}$$+0.3','interpreter','latex')
 - will not be managed by Spring/ [managed: 15; max: 15]
			
检查事务配置 检查 mybatis 配置文件扫描路径是否正确 <!-- 自动扫描 --> <context:component-scan base-package="com ...
 - thrift安装及python和c++版本调试
			
一.安装过程 1.安装依赖库 ]# yum install boost-devel-static libboost-dev libboost-test-dev libboost-program-opt ...
 - day12 函数对象,名称空间与作用域
			
""" 今日内容: 1.函数参数传值细节 2.三元表达式 3.列表及字典推导式 4.函数对象 5.名称空间与作用域 6.函数的嵌套定义初识 ""&qu ...
 - 【转】Python3—UnicodeEncodeError 'ascii' codec can't encode characters in position 0-1
			
转自:https://blog.csdn.net/AckClinkz/article/details/78538462 环境 >>> import sys >>> ...
 - CV code references
			
转:http://www.sigvc.org/bbs/thread-72-1-1.html 一.特征提取Feature Extraction: SIFT [1] [Demo program][SI ...
 - mingw-gcc-8.3.0-i686-posix-sjlj
			
网上无法找到 gcc-8.3.0 的 posix 版本, 所以自己编译了这个版本 gcc -v Using built-in specs. COLLECT_GCC=d:\msys\mingw\bin\ ...
 - 013_UDP专项研究监控
			
数据源: /proc/net/snmp; 采集方式:累计值,每10秒采集一次取差值: 指标:net.snmp.udp (key: system); Out Datagrams: udp层发送的数据包总 ...