[Cpp] view plaincopyprint? /*
Potential Sink upper and lower bounds for Feasible Flow
A source sink can be converted to a non-Source Sink: add an edge t ~ S (0, 0x7fffffff) becomes a non-Source Sink
The basic process is:
Create an additional network (add the necessary arc for the new source sink separation)
Find the maximum flow of the attached network
If the adjacent edge of the New Source Sink is full, a feasible stream exists.
Question:
There is a table that provides the sum of each row and the sum of each column and some elements.
Find a qualified table
After adding a new source sink, separate the necessary arcs (one end must be a new source or sink, and a full stream is required to have a feasible Stream)
There are two types at this time (New Source ss sinhui tt ):
1. Add (u, v) traffic to the upper and lower bounds (ss, v) and (u, tt) traffic are lower bounds
It can be understood as follows: (u, v) the traffic is between the upper and lower bounds because the lower bound traffic is 0.
(Ss, v) the lower-bound traffic is because the lower-bound traffic in (u, v) needs to be added
(U, tt) the traffic is the lower-bound traffic that flows from the u and cannot pass all (u, v). The lower-bound traffic goes directly to the tt through this edge.
This is what I mentioned in the above article, but he uses the second one when writing.
2. add (u, v) traffic to the upper and lower bounds (ss, u) and (u, tt) the traffic is the sum of all lower-bound flows into u minus all lower-bound flows from u (shown in the figure)
The two methods are based on the edge points.
Separates the lower bound of an edge or vertex so that the lower bound of all edges or points is 0 and converts it to a normal maximum flow problem.
The lower bound is directly provided by the ss or directly routed to the tt
*/
# Include <iostream>
# Include <string>
Using namespace std;
# Define N 235
Int map [N] [N], m, n, s, t, x, y, up [N] [N], low [N] [N], yu [N], num [N], d [N];
Int min (int a, int B) {return a <B? A: B ;}
Int max (int a, int B) {return a> B? A: B ;}
Void ini ()
{
Memset (low, 0, sizeof (low ));
Memset (map, 0, sizeof (map ));
Memset (yu, 0, sizeof (yu ));
For (int I = 0; I <= m; ++ I)
For (int j = 0; j <= n; ++ j)
Up [I] [j] = 0x7fffffff;
}
Int build ()
{
For (int I = 1; I <= m; I ++)
For (int j = 1; j <= n; j ++)
If (low [I] [j]> up [I] [j]) return 0;
Else {
Yu [I]-= low [I] [j], yu [j + m] + = low [I] [j]; // here m is written as n
Map [I] [j + m] = up [I] [j]-low [I] [j];
}
Return 1;
}
Int sap (int u, int f)
{
If (u = y) // reach the end point
Return f;
Int v, mind = y, last = f, cost; // mind = point-1 if it starts from 0, it is the last point
For (v = 0; v <= y; ++ v)
{
If (map [u] [v]> 0)
{
If (d [u] = d [v] + 1)
{
Cost = sap (v, min (last, map [u] [v]);
Map [u] [v]-= cost;
Map [v] [u] + = cost;
Last-= cost;
If (d [x]> = y + 1)
Return f-last;
If (last = 0)
Break;
}
If (d [v] <mind)
Mind = d [v];
}
}
If (last = f)
{
-- Num [d [u];
If (num [d [u] = 0)
D [x] = y + 1;
D [u] = mind + 1;
++ Num [d [u];
}
Return f-last;
}
Void limitflow ()//
{
Int I, j, c = 0; // maximum traffic of the c stream
X = t + 1, y = t + 2; // New Source Sink
For (I = s; I <= t; ++ I)
If (yu [I]> 0) map [x] [I] = yu [I]; // necessary arc
Else if (yu [I] <0) map [I] [y] =-yu [I]; // necessary arc
Map [t] [s] = 0x7fffff; // change the source image to a non-source sink.
Memset (d, 0, sizeof (d ));
Memset (num, 0, sizeof (num ));
For (num [x] = y + 1; d [x] <y + 1;) // y + 1 points
C + = sap (x, 0x7fffffff); // use sap to find the maximum stream
For (I = s; I <= t; ++ I) // determines whether the stream is full.
If (map [x] [I])
{
Cout <"IMPOSSIBLE" <endl;
Return;
}
For (I = 1; I <= m; ++ I) // output feasible stream
{
For (j = 1; j <n; ++ j)
Cout <(up [I] [j]-map [I] [j + m]) <"; // upper bound-unincrementing part
Cout <(up [I] [n]-map [I] [n + m]) <endl;
}
Cout <endl;
}
Int main ()
{
Int cas, sum1, sum2, I, j, a, B, num, c, f1, f2, t1, t2;
String op;
Cin> cas;
While (cas --)
{
Cin> m> n;
S = 0, t = m + n + 1, sum1 = sum2 = 0;
Ini ();
For (I = 1; I <= m; ++ I) cin> a, yu [s]-= a, yu [I] + =, sum1 + =;
For (; I <= m + n; ++ I) cin> a, yu [I]-= a, yu [t] + = a, sum2 + =;
Cin> c;
While (c --) // The processing method is good.
{
Cin> a> B> op> num;
F1 = t1 =;
F2 = t2 = B;
If (a = 0)
F1 = 1, t1 = m;
If (B = 0)
F2 = 1, t2 = n;
For (I = f1; I <= t1; ++ I)
For (j = f2; j <= t2; ++ j)
If (op [0] = ')
Low [I] [j] = max (num, low [I] [j]), up [I] [j] = min (num, up [I] [j]);
Else if (op [0] = '> ')
Low [I] [j] = max (num + 1, low [I] [j]);
Else if (op [0] = '<')
Up [I] [j] = min (num-1, up [I] [j]);
}
If (sum1 = sum2 & build () limitflow ();
Else cout <"IMPOSSIBLE" <endl;
}
Return 0;
}
/*
Potential Sink upper and lower bounds for Feasible Flow
A source sink can be converted to a non-Source Sink: add an edge t ~ S (0, 0x7fffffff) becomes a non-Source Sink
The basic process is:
Create an additional network (add the necessary arc for the new source sink separation)
Find the maximum flow of the attached network
If the adjacent edge of the New Source Sink is full, a feasible stream exists.
Question:
There is a table that provides the sum of each row and the sum of each column and some elements.
Find a qualified table
A more detailed description of http://blog.csdn.net/water_glass/article/details/6823741
After adding a new source sink, separate the necessary arcs (one end must be a new source or sink, and a full stream is required to have a feasible Stream)
There are two types at this time (New Source ss sinhui tt ):
1. Add (u, v) traffic to the upper and lower bounds (ss, v) and (u, tt) traffic are lower bounds
It can be understood as follows: (u, v) the traffic is between the upper and lower bounds because the lower bound traffic is 0.
(Ss, v) the lower-bound traffic is because the lower-bound traffic in (u, v) needs to be added
(U, tt) the traffic is the lower-bound traffic that flows from the u and cannot pass all (u, v). The lower-bound traffic goes directly to the tt through this edge.
This is what I mentioned in the above article, but he uses the second one when writing.
2. add (u, v) traffic to the upper and lower bounds (ss, u) and (u, tt) the traffic is the sum of all lower-bound flows into u minus all lower-bound flows from u (shown in the figure)
The two methods are based on the edge points.
Separates the lower bound of an edge or vertex so that the lower bound of all edges or points is 0 and converts it to a normal maximum flow problem.
The lower bound is directly provided by the ss or directly routed to the tt
*/
# Include <iostream>
# Include <string>
Using namespace std;
# Define N 235
Int map [N] [N], m, n, s, t, x, y, up [N] [N], low [N] [N], yu [N], num [N], d [N];
Int min (int a, int B) {return a <B? A: B ;}
Int max (int a, int B) {return a> B? A: B ;}
Void ini ()
{
Memset (low, 0, sizeof (low ));
Memset (map, 0, sizeof (map ));
Memset (yu, 0, sizeof (yu ));
For (int I = 0; I <= m; ++ I)
For (int j = 0; j <= n; ++ j)
Up [I] [j] = 0x7fffffff;
}
Int build ()
{
For (int I = 1; I <= m; I ++)
For (int j = 1; j <= n; j ++)
If (low [I] [j]> up [I] [j]) return 0;
Else {
Yu [I]-= low [I] [j], yu [j + m] + = low [I] [j]; // here m is written as n
Map [I] [j + m] = up [I] [j]-low [I] [j];
}
Return 1;
}
Int sap (int u, int f)
{
If (u = y) // reach the end point
Return f;
Int v, mind = y, last = f, cost; // mind = point-1 if it starts from 0, it is the last point
For (v = 0; v <= y; ++ v)
{
If (map [u] [v]> 0)
{
If (d [u] = d [v] + 1)
{
Cost = sap (v, min (last, map [u] [v]);
Map [u] [v]-= cost;
Map [v] [u] + = cost;
Last-= cost;
If (d [x]> = y + 1)
Return f-last;
If (last = 0)
Break;
}
If (d [v] <mind)
Mind = d [v];
}
}
If (last = f)
{
-- Num [d [u];
If (num [d [u] = 0)
D [x] = y + 1;
D [u] = mind + 1;
++ Num [d [u];
}
Return f-last;
}
Void limitflow ()//
{
Int I, j, c = 0; // maximum traffic of the c stream
X = t + 1, y = t + 2; // New Source Sink
For (I = s; I <= t; ++ I)
If (yu [I]> 0) map [x] [I] = yu [I]; // necessary arc
Else if (yu [I] <0) map [I] [y] =-yu [I]; // necessary arc
Map [t] [s] = 0x7fffff; // change the source image to a non-source sink.
Memset (d, 0, sizeof (d ));
Memset (num, 0, sizeof (num ));
For (num [x] = y + 1; d [x] <y + 1;) // y + 1 points
C + = sap (x, 0x7fffffff); // use sap to find the maximum stream
For (I = s; I <= t; ++ I) // determines whether the stream is full.
If (map [x] [I])
{
Cout <"IMPOSSIBLE" <endl;
Return;
}
For (I = 1; I <= m; ++ I) // output feasible stream
{
For (j = 1; j <n; ++ j)
Cout <(up [I] [j]-map [I] [j + m]) <"; // upper bound-unincrementing part
Cout <(up [I] [n]-map [I] [n + m]) <endl;
}
Cout <endl;
}
Int main ()
{
Int cas, sum1, sum2, I, j, a, B, num, c, f1, f2, t1, t2;
String op;
Cin> cas;
While (cas --)
{
Cin> m> n;
S = 0, t = m + n + 1, sum1 = sum2 = 0;
Ini ();
For (I = 1; I <= m; ++ I) cin> a, yu [s]-= a, yu [I] + =, sum1 + =;
For (; I <= m + n; ++ I) cin> a, yu [I]-= a, yu [t] + = a, sum2 + =;
Cin> c;
While (c --) // The processing method is good.
{
Cin> a> B> op> num;
F1 = t1 =;
F2 = t2 = B;
If (a = 0)
F1 = 1, t1 = m;
If (B = 0)
F2 = 1, t2 = n;
For (I = f1; I <= t1; ++ I)
For (j = f2; j <= t2; ++ j)
If (op [0] = ')
Low [I] [j] = max (num, low [I] [j]), up [I] [j] = min (num, up [I] [j]);
Else if (op [0] = '> ')
Low [I] [j] = max (num + 1, low [I] [j]);
Else if (op [0] = '<')
Up [I] [j] = min (num-1, up [I] [j]);
}
If (sum1 = sum2 & build () limitflow ();
Else cout <"IMPOSSIBLE" <endl;
}
Return 0;
}
Author: qq172108805