POJ 3169 Layout (差分约束系统,Bellman-Ford)

题目链接:http://poj.org/problem?id=3169

输入:

4 2 1
1 3 10
2 4 20
2 3 3

输出:

27

题意:第一行N头牛, 编号1 – N排成一列, 然后ML, MD。然后接下来ML行每行AL,BL,CL表示牛AL和牛BL之间的距离不能超过CL, 然后MD行每行AD,BD,CD表示牛AD和牛BD之间距离不能超过CD。求能满足以上条件的1号牛到N号牛的最大距离。无解输出-1, 无限大输出-2。

——挑战程序设计竞赛

差分约束系统,可将其转化为求最短路径的问题。




#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int MAX_N = 1010;
const int MAX_ML = 10100;
const int MAX_MD = 10100;
int N, ML, MD;
int AL[MAX_ML], BL[MAX_ML], CL[MAX_ML];
int AD[MAX_MD], BD[MAX_MD], CD[MAX_MD];

int dis[MAX_N];
void solve() {
	memset(dis, 0x3f, sizeof(dis));
	dis[1] = 0;
	
	int i, j;
	//Bellman-ford算法 
	for(i = 0; i < N; i++) { 
		for(j = 1; j <= N - 1; j++) {  //从j + 1到 j 的边权值为0 
			dis[j] = min(dis[j], dis[j + 1]);
		}
		for(j = 1; j <= ML; j++) {  //从AL[j]到BL[j]的边权值为CL[j] 
			dis[BL[j]] = min(dis[BL[j]], dis[AL[j]] + CL[j]);
		}
		for(j = 1; j <= MD; j++) {  //从BD[j]到AD[j]的边权值为-CD[j] 
			dis[AD[j]] = min(dis[AD[j]], dis[BD[j]] - CD[j]);
		}
	}
	int flag = 0;  //判断是否存在负圈 
	for(j = 1; j <= N - 1; j++) {
		if(dis[j] > dis[j + 1]) flag = 1;
	}
	for(j = 1; j <= ML; j++) {
		if(dis[BL[j]] > dis[AL[j]] + CL[j]) flag = 1;
	}
	for(j = 1; j <= MD; j++) {
		if(dis[AD[j]] > dis[BD[j]] - CD[j]) flag = 1;
	}
	int res = dis[N];
	if(flag == 1) res = -1;
	//if(d[1] < 0) res = -1; //直接这样写也可以判断负圈,不明白为什么... 
	else if(res == inf) res = -2;  
	printf("%d\n", res);
}
int main() {
	scanf("%d %d %d", &N, &ML, &MD);
	int i;
	for(i = 1; i <= ML; i++) {
		scanf("%d %d %d", AL + i, BL + i, CL + i);
	}
	for(i = 1; i <= MD; i++) {
		scanf("%d %d %d", AD + i, BD + i, CD + i);
	}
	solve();
	return 0;
}





d
[
B
L
]

d
[
A
L
]

D
L

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/Strokess/article/details/52097226
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞