又是差分约束,比上题稍为简单,对于为什么把d[n]设为0作为源点还不是非常理解,还要多加练习。关于bellman-ford算法,可增加一个flag,当边循环没有一条边松驰时,就可以跳出外层循环了,可提高一些效率
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct Edge
{
int u;
int v;
int w;
};
static int n, m, d[1001];
static int bellman_ford(struct Edge *array)
{
int i, j, u, v, w, flag;
for (i = 0; i <= n; i++)
d[i] = INT_MAX;
d[n] = 0;
for (i = 0; i < n; i++)
{
flag = 0;
for (j = 0; j < 2 * n + m; j++)
{
u = array[j].u;
v = array[j].v;
w = array[j].w;
if (d[u] != INT_MAX && d[u] + w < d[v])
{
d[v] = d[u] + w;
flag = 1;
}
}
if (!flag)
break;
}
for (j = 0; j < 2 * n + m; j++)
{
u = array[j].u;
v = array[j].v;
w = array[j].w;
if (d[u] != INT_MAX && d[u] + w < d[v])
return 0;
}
return 1;
}
int main()
{
struct Edge *array = malloc(12000 * sizeof(struct Edge));
while (scanf("%d %d", &n, &m) != EOF)
{
int i, a, b, c;
for (i = 0; i < n; i++)
{
array[2 * i].u = i;
array[2 * i].v = i + 1;
scanf("%d", &(array[2 * i].w));
array[2 * i + 1].u = i + 1;
array[2 * i + 1].v = i;
array[2 * i + 1].w = 0;
}
for (i = 2 * n; i < m + 2 * n; i++)
{
scanf("%d %d %d", &a, &b, &c);
array[i].u = b;
array[i].v = a - 1;
array[i].w = -c;
}
if (bellman_ford(array))
printf("%d\n", -d[0]);
else
puts("Bad Estimations");
}
free(array);
return 0;
}