SGU 298 King Berl VI difference constraint and make min (dis [n]-dis [1]), sguberl
Question link: Click the open link
Question:
Given n points and m constraints.
Output u v x below:
Dis [u]-dis [v]> = x
Then, the image is shown as follows: u-> v edge weight is-x.
Output A solution meeting-10000 <= dis [I] <= 10000.
If there are multiple solutions, output the smallest solution of dis [n]-dis [1.
Ideas:
The maximum solution is obtained in the positive graph, and the partial solution is obtained in the reverse graph. For the maximum solution <partial solution of a vertex, the difference constraint does not exist.
If the problem requires that dis [n]-dis [1] be the smallest, the dis [n] should be the ultimate solution, and dis [1] should be the greatest solution. Just spfa again.
Note: The greatest solution mentioned here requires a variable to be determined. Then this variable is (max (dis [I]) = inf)
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <vector>#include <set>#include <math.h>#include <map>#include <queue>using namespace std;#define N 10010#define M 100010#define inf 10000struct Edge{int to, dis, nex;};int inq[N], Tim[N];int n, m;bool spfa(int head[], Edge edge[], int dis[]){queue<int> q; for(int i = 1; i <= n; i++) Tim[i] = 0, inq[i] = 1, q.push(i);while(!q.empty()){int u = q.front(); q.pop(); inq[u] = 0;for(int i = head[u]; ~i; i = edge[i].nex){int v = edge[i].to;if(dis[v] > dis[u] + edge[i].dis) {dis[v] = dis[u]+edge[i].dis;if(!inq[v]) {Tim[v]++;if(Tim[v] > n) return false;inq[v] = 1;q.push(v);}}}}return true;}Edge edge[M], Fedge[M];int head[N], edgenum, fan[N];void init(){memset(head, -1, sizeof head); memset(fan, -1, sizeof fan); edgenum = 0; }void add(int u, int v, int d){Edge E = {v, d, head[u]};edge[edgenum] = E;head[u] = edgenum;Edge E2 = {u, d, fan[v]};Fedge[edgenum] = E2; fan[v] = edgenum++;}int disg[N], disr[N];int solve(){init();int u, v, d;while(m--){scanf("%d %d %d", &u, &v, &d);add(u, v, -d);}for(int i = 1; i <= n; i++) disg[i] = inf;if(spfa(head, edge, disg)==false) return -1;for(int i = 1; i <= n; i++) disr[i] = inf;if(spfa(fan, Fedge, disr)==false) return -1;for(int i = 1; i <= n; i++)if(disg[i] < -disr[i])return -1;disg[n] = -disr[n];spfa(head, edge, disg);for(int i = 1; i <= n; i++)printf("%d%c", disg[i], i==n?'\n':' ');return 0;}int main(){while(cin>>n>>m)if(solve()==-1)puts("-1");return 0;}/*3 31 2 12 1 13 1 23 31 2 12 1 -13 1 23 31 2 12 1 -11 3 2*/