(Luogu) P1993 小K的农场 (差分约束)

传送门

解题思路:这是一道差分约束的裸题,我也是第一次接触差分约束,(详细解说戳我)简单来说,就是将不等式 与 spfa里的松弛操作联系起来,给予他意义,这样就可以用图的方式来解决他了,观察等式 a-b<=k ,这个式子可以变成 a<=b+k 这个式子是不很像

spfa里的松弛操作
if(d[v] < d[u] + w(u,v) ) {
        d[v] = d[u] + w(u, v);
}

我们可以将a看成d[v], b看成d[u], 那么k就是u到v这条边上的权值了,然后就可以建图。

而这个题目,他给的至多和至少就是这样的不等式(都化简成小于等于),而等于,那就建两条权值为0的边,然后可以还是不可以呢,那就判断有没有环,有环那就矛盾了。深搜判断环比宽搜快很多。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=1e4+5;
int n,m;
struct node {
	int to,w;
};
vector<node> eg[maxn];
int dist[maxn],vis[maxn];
bool spfa(int st) {
	vis[st]=1;
	int to,w;
	node tp;
	for(int i=0; i<(int)eg[st].size(); ++i) {
		tp=eg[st][i];
		to=tp.to,w=tp.w;
		if(dist[to]>dist[st]+w) {
			dist[to]=dist[st]+w;
			if(vis[to] || spfa(to))	return 1;
		}
	}
	vis[st]=0;
	return 0;
}
int main() {
	std::ios::sync_with_stdio(0);
	cin>>n>>m;
	int x,a,b,c;
	for(int i=1; i<=m; ++i) {
		cin>>x;
		if(x==1) {
			cin>>a>>b>>c;
			eg[a].push_back(node {b,-c});
		}
		if(x==2) {
			cin>>a>>b>>c;
			eg[b].push_back(node {a,c});
		}
		if(x==3) {
			cin>>a>>b;
			eg[a].push_back(node {b,0});
			eg[b].push_back(node {a,0});
		}
	}
	for(int i=1;i<=n;++i){
		if(spfa(i)){
			cout<<"No"<<endl;
			return 0;
		}
	} 
	cout<<"Yes"<<endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值