poj 3169 Layout 差分约束
设d[i] 为 第i只牛到第1只牛的距离
根据题意有:
d[1] = 0;
d[b] - d[a] <= D(ml)
d[b] – d[a] >= D(md)
d[i] – d[i-1] >= 0 题目说牛是从1~n排列下去,这是题目隐藏的条件,刚开始没有加这个条件也能ac
d[i] – d[1] >= 0 (1<= i <= n)
以1为源点开始搜索,d[n]就是答案,当d[n] = INF时,说明n是自由点,输出-2
#include <iostream>
#include <queue>
using namespace std;
const int MAX = 50000;
const int INF = 1000000000;
const int N = 1005;
struct Node
{
int v;
int cost;
int next;
};
Node node[MAX];
int adj[N];
int d[N];
bool in_q[N];
queue<int> Q;
int size;
int n, ml, md;
int cnt[N];
void add_edge(int u, int v, int cost)
{
node[size].v = v;
node[size].cost = cost;
node[size].next = adj[u];
adj[u] = size++;
}
bool spfa()
{
memset(in_q, false, sizeof(in_q));
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i <= n; i++)
d[i] = INF;
d[1] = 0;
in_q[1] = true;
Q.push(1);
int u, v, w;
while (!Q.empty())
{
u = Q.front();
Q.pop();
in_q[u] = false;
for (int i = adj[u]; i != -1; i = node[i].next)
{
v = node[i].v;
w = node[i].cost;
if (d[v] > d[u] + w)
{
d[v] = d[u] + w;
if (!in_q[v])
{
in_q[v] = true;
Q.push(v);
}
if (++cnt[v] > n) return false;
}
}
}
return true;
}
int main()
{
int a, b, c;
scanf("%d%d%d", &n, &ml, &md);
for (int i = 0; i <= n; i++)
adj[i] = -1;
size = 0;
for (int i = 0; i < ml; i++)
{
scanf("%d%d%d", &a, &b, &c);
add_edge(a, b, c); //d[b] - d[a] <= c
}
for (int i = 0; i < md; i++)
{
scanf("%d%d%d", &a, &b, &c);
add_edge(b, a, -c); //d[a] - d[b] <= -c
}
for (int i = 2; i <= n; i++)
{
add_edge(i, 1, 0); //d[1] - d[i] <= 0
add_edge(i, i-1, 0); //d[i-1] - d[i] <= 0
}
if (spfa())
{
if (d[n] == INF)
printf("-2\n");
else
printf("%d\n", d[n]);
}
else
printf("-1\n");
return 0;
}
浙公网安备 33010602011771号