This question seems to be easy to build. In fact, the maximum flow with bare minimum cost will inevitably Time Out, And the zkw billing flow will also time out.
Therefore, you must understand the meaning of the question. The question must be better than the current solution, and the question should be the best.
According to the theorem, a fee flow is a sufficient condition for the minimum cost flow, that is, the residual network of the fee flow has no negative charge circle. If you do not understand this theorem, you can draw a picture.
For this question, you only need to cancel the circle once to find a better solution than the current solution. Of course, the premise is that there is a negative circle in the network.
At this time, you only need to increase the traffic of each side by 1 along the negative billing cycle (this negative billing cycle has a reverse edge, and the inverse edge traffic plus 1 is equivalent to the corresponding positive edge traffic minus 1 ), the solution corresponding to the residual network after the stream adding is definitely a better solution.
So how can we establish a residual network based on existing traffic.
It is actually a process of reverse thinking.
All buildings I and shelter j are connected to ij, And the edge weight is positive distance. Because I, the capacity between j must be infinite
If the original scheme I has someone to j, connect to ji, and the edge weight is negative. If I to j has traffic, the capacity of j to I is greater than 0, and the cost is negative, because this is determined by the edge created by the smallest cost and the largest stream.
If the number of j shelters is greater than 0, the connection points and j are connected, and the edge weight is 0.
If the j refuge is not full, connect j and the sink, and the edge weight is 0.
[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <cstring>
# Include <string>
# Include <cstdio>
# Include <cmath>
# Include <queue>
# Include <map>
# Include <set>
# Define eps 1e-5
# Define maxn555
# Define MAXM 55555
# Define INF 100000007
Using namespace std;
Struct P
{
Int x, y, w;
} A [MAXN], B [MAXN];
Struct EDGE
{
Int v, w, next;
} Edge [MAXM];
Int head [MAXN], e;
Int d [MAXN], vis [MAXN], pre [MAXN], cnt [MAXN];
Int que [MAXN * MAXN];
Int nt, n, m;
Int ans [MAXN] [MAXN], g [MAXN] [MAXN], sum [MAXN];
Void init ()
{
E = 0;
Memset (head,-1, sizeof (head ));
Memset (cnt, 0, sizeof (cnt ));
Memset (pre,-1, sizeof (pre ));
}
Void add (int u, int v, int w)
{
Edge [e]. v = v;
Edge [e]. w = w;
Edge [e]. next = head [u];
Head [u] = e ++;
}
Int spfa (int src)
{
For (int I = 0; I <= n; I ++) d [I] = INF, vis [I] = 0;
Vis [src] = 1;
Int h = 0, t = 0;
Que [t ++] = src;
D [src] = 0;
Cnt [src] ++;
While (h <t)
{
Int u = que [h ++];
Vis [u] = 0;
For (int I = head [u]; I! =-1; I = edge [I]. next)
{
Int v = edge [I]. v;
Int w = edge [I]. w;
If (d [u] + w <d [v])
{
D [v] = d [u] + w;
Pre [v] = u;
If (! Vis [v])
{
Vis [v] = 1;
Que [t ++] = v;
If (++ cnt [v]> n) return v;
}
}
}
}
Return-1;
}
Int main ()
{
Scanf ("% d", & nt, & m );
Init ();
For (int I = 0; I <nt; I ++) scanf ("% d", & a [I]. x, & a [I]. y, & a [I]. w );
For (int I = 0; I <m; I ++) scanf ("% d", & B [I]. x, & B [I]. y, & B [I]. w );
N = nt + m;
For (int I = 0; I <nt; I ++)
For (int j = 0; j <m; j ++)
{
G [I] [j] = abs (a [I]. x-B [j]. x) + abs (a [I]. y-B [j]. y) + 1;
Add (I, j + nt, g [I] [j]);
}
For (int I = 0; I <nt; I ++)
For (int j = 0; j <m; j ++)
{
Scanf ("% d", & ans [I] [j]);
If (ans [I] [j])
{
Add (j + nt, I,-g [I] [j]);
Sum [j] + = ans [I] [j];
}
}
For (int I = 0; I <m; I ++)
{
If (sum [I] <B [I]. w) add (I + nt, nt + m, 0 );
If (sum [I]> 0) add (nt + m, I + nt, 0 );
}
Int u = spfa (nt + m );
If (u =-1) printf ("OPTIMAL \ n ");
Else
{
Printf ("SUBOPTIMAL \ n ");
Memset (vis, 0, sizeof (vis ));
Int v = u;
While (! Vis [v])
{
Vis [v] = 1;
V = pre [v];
}
U = v;
Do
{
If (pre [v] <nt & v> = nt) ans [pre [v] [v-nt] ++;
If (v <nt & pre [v]> = nt) ans [v] [pre [v]-nt] --;
V = pre [v];
} While (v! = U );
For (int I = 0; I <nt; I ++)
For (int j = 0; j <m; j ++)
{
If (j = m-1) printf ("% d \ n", ans [I] [j]);
Else printf ("% d", ans [I] [j]);
}
}
Return 0;
}
# Include <iostream>
# Include <algorithm>
# Include <cstring>
# Include <string>
# Include <cstdio>
# Include <cmath>
# Include <queue>
# Include <map>
# Include <set>
# Define eps 1e-5
# Define maxn555
# Define MAXM 55555
# Define INF 100000007
Using namespace std;
Struct P
{
Int x, y, w;
} A [MAXN], B [MAXN];
Struct EDGE
{
Int v, w, next;
} Edge [MAXM];
Int head [MAXN], e;
Int d [MAXN], vis [MAXN], pre [MAXN], cnt [MAXN];
Int que [MAXN * MAXN];
Int nt, n, m;
Int ans [MAXN] [MAXN], g [MAXN] [MAXN], sum [MAXN];
Void init ()
{
E = 0;
Memset (head,-1, sizeof (head ));
Memset (cnt, 0, sizeof (cnt ));
Memset (pre,-1, sizeof (pre ));
}
Void add (int u, int v, int w)
{
Edge [e]. v = v;
Edge [e]. w = w;
Edge [e]. next = head [u];
Head [u] = e ++;
}
Int spfa (int src)
{
For (int I = 0; I <= n; I ++) d [I] = INF, vis [I] = 0;
Vis [src] = 1;
Int h = 0, t = 0;
Que [t ++] = src;
D [src] = 0;
Cnt [src] ++;
While (h <t)
{
Int u = que [h ++];
Vis [u] = 0;
For (int I = head [u]; I! =-1; I = edge [I]. next)
{
Int v = edge [I]. v;
Int w = edge [I]. w;
If (d [u] + w <d [v])
{
D [v] = d [u] + w;
Pre [v] = u;
If (! Vis [v])
{
Vis [v] = 1;
Que [t ++] = v;
If (++ cnt [v]> n) return v;
}
}
}
}
Return-1;
}
Int main ()
{
Scanf ("% d", & nt, & m );
Init ();
For (int I = 0; I <nt; I ++) scanf ("% d", & a [I]. x, & a [I]. y, & a [I]. w );
For (int I = 0; I <m; I ++) scanf ("% d", & B [I]. x, & B [I]. y, & B [I]. w );
N = nt + m;
For (int I = 0; I <nt; I ++)
For (int j = 0; j <m; j ++)
{
G [I] [j] = abs (a [I]. x-B [j]. x) + abs (a [I]. y-B [j]. y) + 1;
Add (I, j + nt, g [I] [j]);
}
For (int I = 0; I <nt; I ++)
For (int j = 0; j <m; j ++)
{
Scanf ("% d", & ans [I] [j]);
If (ans [I] [j])
{
Add (j + nt, I,-g [I] [j]);
Sum [j] + = ans [I] [j];
}
}
For (int I = 0; I <m; I ++)
{
If (sum [I] <B [I]. w) add (I + nt, nt + m, 0 );
If (sum [I]> 0) add (nt + m, I + nt, 0 );
}
Int u = spfa (nt + m );
If (u =-1) printf ("OPTIMAL \ n ");
Else
{
Printf ("SUBOPTIMAL \ n ");
Memset (vis, 0, sizeof (vis ));
Int v = u;
While (! Vis [v])
{
Vis [v] = 1;
V = pre [v];
}
U = v;
Do
{
If (pre [v] <nt & v> = nt) ans [pre [v] [v-nt] ++;
If (v <nt & pre [v]> = nt) ans [v] [pre [v]-nt] --;
V = pre [v];
} While (v! = U );
For (int I = 0; I <nt; I ++)
For (int j = 0; j <m; j ++)
{Www.2cto.com
If (j = m-1) printf ("% d \ n", ans [I] [j]);
Else printf ("% d", ans [I] [j]);
}
}
Return 0;
}
Author: sdj222555