题目链接。
分析:
对于任意i号奶牛,1<=i<N,在距离上应该满足:
D[i+1] - D[i] >= 0
对于每个好感的描述(i,j,k),假设i<=j,体现到距离上的要求就是:
D[j] - D[i] <= k
对于每个反感的描述(i,j,k),假设i<=j,体现到距离上的要求就是:
D[j] - D[i] >= k
写成我们约定的形式:
D[i] - D[i+1] <= 0
D[j] -D[i ]<= k
D[i] - D[j] <= - k
1.对于差分不等式,a - b <= c ,建一条 b 到 a 的权值为 c 的边,求的是最短路,得到的是最大值(本题求的就是最大值),对于不等式 a - b >= c ,建一条 b 到 a 的权值为 c 的边,求的是最长路,得到的是最小值。
2.如果检测到负环,那么无解。
3.如果d[]没有更新,那么可以是任意解。
Bellman Ford AC代码如下:
#include <stdio.h> #define MAXN 1010 #define MAXM 20010 const int INF = (1<<24); struct node{ int u, v, w; }edge[MAXM]; int n, m, top, d[MAXN]; void Init(){ top = 0; } void sort(int *a, int *b){ int t; if(*a > *b){ t = *a; *a = *b; *b = t; } } void add(int u, int v, int w){ edge[top].u = u; edge[top].v = v; edge[top++].w = w; } int bellman_ford(){ int i, j, u, v, w; for(i=1; i<=n; i++) d[i] = INF; d[1] = 0; for(i=1; i<n; i++){ for(j=0; j<m; j++){ u = edge[j].u; v = edge[j].v; w = edge[j].w; if(d[u] < INF && d[u]+w<d[v]){ d[v] = d[u]+w; } } } for(j=0; j<m; j++){ //检测负环 u = edge[j].u; v = edge[j].v; w = edge[j].w; if(d[u] < INF && d[u]+w<d[v]){ return 0; } } return 1; } int main(){ int ml, md, i, u, v, w; scanf("%d %d %d", &n, &ml, &md); Init(); m = ml+md; for(i=0; i<ml; i++){ scanf("%d %d %d", &u, &v, &w); sort(&u, &v); add(u, v, w); } for(i=0; i<md; i++){ scanf("%d %d %d", &u, &v, &w); sort(&u, &v); add(v, u, -w); } if(bellman_ford() == 0){ printf("-1\n"); } else if(d[n] == INF){ printf("-2\n"); } else printf("%d\n", d[n]); return 0; }