差分约束 刷题记录
把问题转化成一堆不等式,然后用最短路求解
POJ3169 Layout
最后要求1和n之间最大dis是多少 -> 转化为得到一堆 d[n] - d[1] <= xi 然后求xi的最小值
对于给出的是d[u] - d[v] >= xi 同乘-1转化为 d[v] - d[u] <= -xi 即可
然后用spfa求 1到n的最短路
若有负环则无解,若求得的最短路为inf则说明1,n间距离可随便大
代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <queue> 4 #define nmax 50010 5 #define f(c,a,b) for(int c=a; c<=b; c++) 6 7 using namespace std; 8 typedef long long ll; 9 struct edge{ 10 int v, ne, w; 11 }e[nmax]; 12 int cnt=0, n, x, y; 13 int head[nmax]={0}, c[nmax]={0}, inq[nmax]={0}; 14 ll d[nmax]={0}; 15 const ll inf = 1e15; 16 17 void addedge(int u, int v, int w){ 18 cnt++; 19 e[cnt].v = v; 20 e[cnt].w = w; 21 e[cnt].ne = head[u]; 22 head[u] = cnt; 23 } 24 25 void build(){ 26 scanf("%d%d%d", &n, &x, &y); 27 int u, v, w; 28 f(i, 1, x){ 29 scanf("%d%d%d", &u, &v, &w); 30 addedge(u, v, w); 31 } 32 f(i, 1, y){ 33 scanf("%d%d%d", &u, &v, &w); 34 addedge(v, u, -w); 35 } 36 f(i, 2, n) d[i] = inf; 37 } 38 39 bool spfa(){ 40 queue <int> q; 41 q.push(1); 42 inq[1] = c[1] = 1; 43 while(!q.empty()){ 44 int u = q.front(); 45 if( c[u] > n ) return false; 46 q.pop(); 47 inq[u] = 0; 48 for (int i=head[u]; i; i=e[i].ne){ 49 int v = e[i].v; 50 if(d[v] > d[u] + e[i].w){ 51 d[v] = d[u] + e[i].w; 52 if(inq[v]) continue; 53 inq[v] = 1; 54 c[v]++; 55 q.push(v); 56 } 57 } 58 } 59 return true; 60 } 61 62 int main(){ 63 build(); 64 if( spfa() ){ 65 if(d[n]==inf) printf("-2\n"); 66 else printf("%lld\n", d[n]); 67 }else{ 68 printf("-1\n"); 69 } 70 return 0; 71 }