ZOJ-1508

来源:互联网 发布:windows installer恢复 编辑:程序博客网 时间:2024/06/09 15:05

做的第一道差分约束。。看了一天的算法导论上的分析加上自己的一些思考,终于磕磕碰碰地把这题给A了,并且基本上理解了思想。。中间还参考了好多大牛的代码和分析。。关于本题有几点要注意,就是除了题目给的约束外还要加上每条线段还要加上两个约束,经典的差分约束是要还要加上一个虚拟点做来连通所有点的,本题不用,因为加上额外约束条件显然所有点都是连通的,还有一个就是源点要以最大点开始,而不是0原点,因为这样才能保证不等式成立,关于这个还想了好久。。

#include<stdio.h>#include<stdlib.h>#include<limits.h>struct Edge{int u;int v;int w;};static int d[50002], edges, points;static int bellman_ford(struct Edge *array, int *d){int i, j, u, v, w, flag;for (i = 0; i < 50002; i++)d[i] = INT_MAX;d[points] = 0;for (i = 0; i < points; i++){flag = 0;for (j = 0; j < edges; 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 < edges; j++)if (d[array[j].u] != INT_MAX && d[array[j].u] + array[j].w < d[array[j].v])return 0;return 1;}int main(){int n;struct Edge *array = malloc(50001 * 3 * sizeof(struct Edge));while (scanf("%d", &n) != EOF){edges = 0;points = -1;int i, a, b, c;while (n--){scanf("%d %d %d", &a, &b, &c);array[edges].u = b + 1;array[edges].v = a;array[edges++].w = -c;if (b + 1 > points)points = b + 1;}for (i = 0; i < points; i++){array[edges].u = i;array[edges].v = i + 1;array[edges++].w = 1;array[edges].u = i + 1;array[edges].v = i;array[edges++].w = 0;}bellman_ford(array, d);printf("%d\n", -d[0]);}free(array);return 0;}


0 0
原创粉丝点击