/**
* @file main.cpp
* @brief 差分约束系统,题意很简单
* 一堆的奶牛,有的两两希望距离x以上,有的希望距离x以下
* 求1到n号奶牛的最大距离,同时注意输出不连通-2以及负环无解-1
*
* 设s[i]表示i号奶牛的绝对距离,则有以下约束:
* 1. s[b] - s[a] <= d
* 2. s[b] - s[a] >= d
*
* 即
* 1. if (s[a] + d < s[b])
* s[b] = s[a] + d
*
* 2. if (s[b] + (-d) < s[a])
* s[a] = s[b] + (-d)
*
* 1. (a, b)添加权值d
* 2. (b, a)添加权值-d
*
* @author yekeren
* @version 1.0.0
* @date 2013-06-07
*/
#include <iostream>
#include <queue>
#define MAX_INT 0x7fffffff
///(M)临接表
struct edge_t {
int b, c;
struct edge_t *next;
} *k[1100], pool[21000];
int npool = 0;
/**
* @brief 添加边
* @param a
* @param b
* @param c
*/
void add_edge(int a, int b, int c)
{
pool[npool].b = b;
pool[npool].c = c;
pool[npool].next = k[a];
k[a] = &pool[npool++];
}
/**
* @brief
* @param n
* @return
*/
int spfa(int n)
{
int s[1100] = { 0 };
for (int i = 1; i <= n; ++i) {
s[i] = MAX_INT;
}
s[1] = 0;
std::queue<int> q;
unsigned char visit[1100] = { 0 };
unsigned short count[1100] = { 0 };
visit[1] = 1;
count[1] = 1;
q.push(1);
while (!q.empty())
{
int u = q.front();
q.pop();
visit[u] = 0;
for (edge_t *p = k[u]; p != NULL; p = p->next)
{
int v = p->b;
int c = p->c;
if (s[u] + c < s[v])
{
s[v] = s[u] + c;
if (!visit[v])
{
visit[v] = 1;
q.push(v);
if (++count[v] > n) {
return -1;
}
}
}
}
}
if (s[n] == MAX_INT) {
return -2;
}
return s[n];
}
int main(int argc, char *argv[])
{
int n, ml, md;
std::cin >> n >> ml >> md;
int a, b, d;
for (int i = 0; i < ml; ++i)
{
std::cin >> a >> b >> d;
add_edge(a, b, d);
}
for (int i = 0; i < md; ++i)
{
std::cin >> a >> b >> d;
add_edge(b, a, -d);
}
std::cout << spfa(n) << std::endl;
return 0;
}
POJ 3169 Layout 差分约束系统
最新推荐文章于 2020-07-16 16:23:32 发布