poj3169 差分约束

关于差分约束,我强推这位大佬的博客。https://blog.csdn.net/consciousman/article/details/53812818
题目是有的牛互相之间最多只能有一个距离,有的牛最少要达到一个距离。
很容易写出不等式,由于是要求最大值,所以是要化为小于等于号,求最短路。
F[i]:表示i只牛在哪个位置
0=< F[B] - F[A] <= D
F[B] - F[A] >= D;
等价于
F[A]- F[B]<= 0;
F[B] - F[A] <= D;
F[A] - F[B] <= -D;
也就是

  1. b连a权值是0
  2. a连b权值是d
  3. b连a权值是-d

然后直接套上去就可以了。判断是否成立就是看有没有一个点进栈n次,进n次就是有环输出-1,如果是f【n】的值是最大值那么说明任意距离都可以输出-2;
下面是代码

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
const int max_ = 1e7 + 7;
int n, head[max_], xiann = 1, ml,md;
inline int read()
{
	int s = 0, f = 1;
	char ch = getchar();
	while (ch<'0' || ch>'9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0'&&ch <= '9') {
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * f;
}
struct k {
	int next, to, value;
}xian[max_];
inline void add_(int a, int b, int c) {
	xian[xiann].next = head[a];
	xian[xiann].to = b;
	xian[xiann].value = c;
	head[a] = xiann;
	xiann++;
}
int vis[max_], pan[max_], f[max_];
void spfa(int now) {
	queue<int> node;
	node.push(now);
	vis[now] = 1;
	while (!node.empty()) {
		int tou = node.front(); node.pop();
		vis[tou] = 0;
		for (int i = head[tou]; i; i = xian[i].next) {
			if (f[tou] + xian[i].value < f[xian[i].to]) {
				f[xian[i].to] = f[tou] + xian[i].value;
				if (vis[xian[i].to] == 0) {
					node.push(xian[i].to);
					vis[xian[i].to] = 1;
					pan[xian[i].to]++;
					if (pan[xian[i].to] >= n) {
						cout << "-1"; exit(0);
					}
				}
			}
		}
	}
}
int main() {
	n = read(), ml = read(), md = read();
	while (ml--) {
		int a = read(), b = read(), d = read();
		add_(b, a, 0);
		add_(a, b, d);
	}
	while (md--) {
		int a = read(), b = read(), d = read();
		add_(b, a, -d);
	}
	for (int i = 2; i <= n; i++) {
		f[i] = max_;
	}
	spfa(1);
	if (f[n] == max_) {
		cout << "-2";
	}
	else {
		cout << f[n];
	}
	return 0;
}

发布了32 篇原创文章 · 获赞 3 · 访问量 676

猜你喜欢

转载自blog.csdn.net/qq_43804974/article/details/101011603