Layout(POJ No.3169)

Layout(POJ No.3169)

POJ 3169
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 10005
#define _for(i, a) for(int i = 0; i < (a); i++)
#define _rep(i, a, b) for(int i = (a); i <= (b); i++)
#define INF 0x3f3f3f3f

int N, ML, MD;
int AL[maxn], BL[maxn], DL[maxn];
int AD[maxn], BD[maxn], DD[maxn];

int d[maxn];

void solve() {
	fill(d, d + N, INF);
	d[0] = 0;

	_for(k, N) {
		for (int i = 0; i + 1 < N; i++) {
			if (d[i + 1] < INF) d[i] = min(d[i], d[i + 1]);
		}
		_for(i, ML) {
			if (d[AL[i] - 1] < INF) {
				d[BL[i] - 1] = min(d[BL[i] - 1], d[AL[i] - 1] + DL[i]);
			}
		}
		_for(i, MD) {
			if (d[BL[i] - 1] < INF) {
				d[AD[i] - 1] = min(d[AD[i] - 1], d[BD[i] - 1] - DD[i]);
			}
		}
	}

	int res = d[N - 1];
	if (d[0] < 0) {
		res = -1;
	}
	else if (res == INF) {
		res = -2;
	}
	printf("%d\n", res);
}

int main() {
	//freopen("in.txt", "r", stdin);
	cin >> N >> ML >> MD;
	_for(i, ML) cin >> AL[i] >> BL[i] >> DL[i];
	_for(i, MD) cin >> AD[i] >> BD[i] >> DD[i];
	solve();
	return 0;
}

/*
假设现在有A, B, C三头牛,其中A和B的关系很好,
它们能忍受的最大距离是AL,那么我们从A开始分析,
这时候B和A的最远距离就是AL;
而B不喜欢C,且它们之间最少要有BL的距离,而且要保证B在C的前面;
这时候只需要把C尽量往后拖就行了,那么A和C的最大距离就是INF;

假设A和C关系很好,而C很讨厌B,而且BL > AL,
这时候无论怎么放就不可能满足所有情况,也就不存在这种排列;

现在假设有A,B,C,D四头牛;
A和C关系很好,而C不喜欢B,B很喜欢d;
那么我们从A开始分析,
这时候C和A的最大距离就是Al,而C不喜欢B,而且要保证B在C前面,
那么为了让D尽可能靠后,那么B就要尽量靠后,
所以B最合适的位置就是d[c] - BL,也就是C能忍受的最小距离;

那么综合分析就是首先在满足已知的排列条件的情况下尽量往后靠,
而一头牛最靠后的位置就是与后一头牛重叠;而后考虑关系好的牛,
让他们的距离尽可能远;最后考虑关系不好的牛,在保证双方在可接受范围内,
同时尽量让牛的位置往后靠;
N-1次循环后只需要看d[0]就能知道是否有解,若有解,
只需要看d[N - 1]就知道答案是否是无限远。
*/
发布了163 篇原创文章 · 获赞 54 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42856843/article/details/102817907