一道简单的差分约束方程,差分约束方程由Bellmanford转换而来,一组差分方程由 x-y <=d 的形式,而在最短路中松弛条件有dis(x)<= dis(y)+w。 所以产生了一条由y连向x的有向边,权重为d。
https://github.com/Sosi/ProgrammingContest/blob/master/OnlineJudge/POJ/PKU3169.cpp
1:
2: #include <queue>
3: #include <iostream>
4: #include <string.h>
5: #include <stdio.h>
6: using namespace std;
7: #define MAXN 1005 // vertex
8: #define MAXM 20005 // edge
9: #define INF 0x3F3F3F3F
10:
11: struct node
12: {
13: int v, w, next;
14: }pnt[MAXM];
15:
16: int head[MAXN];
17: int dis[MAXN];
18: bool vis[MAXN];
19: int cnt[MAXN]; // the number of the operation of push to Quque. negatvie cycle.
20: int num = 0; // the index of the edge
21: int N ; // the number of the vertex.
22: int M ; // the number of edges
23: int src, sink;
24: void addedge(int u, int v, int w)
25: {
26: pnt[num].v = v; pnt[num].w= w;
27: pnt[num].next = head[u]; head[u] = num++;
28: }
29:
30: int SPFA()
31: {
32: for(int i=0; i<=N; i++)
33: {
34: vis[i]=0; dis[i] = INF; cnt[i] = 0;
35: }
36:
37: queue<int> Q;
38: Q.push(src); vis[src] = 1; dis[src] = 0; ++cnt[src];
39: while(!Q.empty())
40: {
41: int u = Q.front(); Q.pop(); vis[u] = 0;
42: for(int i=head[u]; i!=-1; i=pnt[i].next)
43: {
44: int v = pnt[i].v;
45: if( dis[v] > dis[u] + pnt[i].w )
46: {
47: dis[v] = dis[u] + pnt[i].w;
48: if(!vis[v]) {Q.push(v); vis[v] = 1;}
49: if( ++cnt[v] > N) return -1; // negative cycle.
50: }
51: }
52: }
53: if(dis[sink] == INF) return -2; // can't from src to sink.
54: return dis[sink];
55: }
56:
57: int main()
58: {
59: int ml,md;
60: while(scanf("%d%d%d", &N , &ml, &md)!= EOF)
61: {
62: num = 0;
63: memset(head, -1, sizeof(head));
64: int a, b, c;
65: for(int i=0; i<ml; i++)
66: {
67: scanf("%d%d%d", &a, &b, &c);
68: if(a>b) swap(a,b);
69: addedge(a, b,c);
70: }
71: for(int i=0; i<md; i++)
72: {
73: scanf("%d%d%d", &a, &b, &c);
74: if(a<b) swap(a,b);
75: addedge(a, b, -c);
76: }
77: src = 1; sink = N;
78: printf("%d\n", SPFA());
79: }
80: return 0;
81: }