[Cpp]
*
Hdu 3157
Poj 3801
A circuit board with N wiring bars (Number 1 ~ N) There are two power supply terminals +-
Then the terminal and minimum current of M parts are given.
Find an impossible output if the total current that can make all parts work normally is not
It is actually a problem of having a source sink with the upper and lower bounds of the smallest stream.
The biggest stream problem with upstream and downstream sources is:
1. Create an additional network
2. Find the maximum stream for the ss and tt (if the ss and tt are full streams, there is a solution)
3. If there is a solution, find the maximum stream for s and t.
The problem of the source sink with the smallest upstream and downstream streams is:
1. Construct an additional network (without adding [t, s] edges)
2. Find the maximum stream for ss and tt
3. Add the [t, s] edge
4. Find the maximum stream for ss and tt
5. If the ss and tt streams are full, the [t, s] traffic is the minimum flow.
Most of the Code is extracted from other questions, and the comments are messy.
*/
# Include <stdio. h>
# Include <string. h>
# Define inf 0x7fffffff
Struct edge // edge
{
Int u, v, f, next, B, c;
} E [1, 1500];
Int head [70], in [70], s, t, ss, tt, yong, sum;
Int n, m;
Void ini ()
{
Memset (head,-1, sizeof (head ));
Yong = 0;
Memset (in, 0, sizeof (in ));
S = 0, t = n + 1, ss = t + 1, tt = ss + 1; // arrangement of node numbers
Sum = 0;
}
Void adde (int from, int to, int xia, int shang) // Edge Addition
{// Edge adding
E [yong]. u = from, e [yong]. v = to, e [yong]. f = shang-xia, e [yong]. B = xia, e [yong]. c = shang;
E [yong]. next = head [from], head [from] = yong ++;
// Add its backend
E [yong]. u = to, e [yong]. v = from, e [yong]. f = 0, e [yong]. B = xia, e [yong]. c = shang;
E [yong]. next = head [to], head [to] = yong ++;
}
Void build ()
{
Int I;
For (I = 0; I <= t; ++ I)
{
If (in [I]> 0)
Adde (ss, I, 0, in [I]);
Else
{
Adde (I, tt, 0,-in [I]);
Sum + = (-in [I]);
}
}
}
Int d [1000], num [1000];
Int min (int a, int B) {return a <B? A: B ;}
Int sap_gap (int u, int f, int s, int t) // recursive sap
{
If (u = t)
Return f;
Int I, v, mind = t, last = f, cost;
For (I = head [u]; I! =-1; I = e [I]. next)
{
V = e [I]. v;
Int flow = e [I]. f;
If (flow> 0) // when writing a reference template, the flow is written as f
{
If (d [u] = d [v] + 1)
{
Cost = sap_gap (v, min (last, flow), s, t );
E [I]. f-= cost;
E [I ^ 1]. f + = cost;
Last-= cost;
If (d [s]> = t + 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 [s] = t + 1;
D [u] = mind + 1;
++ Num [d [u];
}
Return f-last;
}
Int max_f (int s, int t)
{
Int f = 0;
Memset (d, 0, sizeof (d ));
Memset (num, 0, sizeof (num ));
For (num [s] = t + 1; d [s] <t + 1 ;)
F + = sap_gap (s, inf, s, t );
Return f;
}
Int main ()
{
Int I, dat, u, v, f1, f2, p;
Char from [10], to [10];
While (scanf ("% d", & n, & m), n + m)
{
Ini ();
For (I = 1; I <= m; ++ I)
{
Scanf ("% s % d", from, to, & dat );
If (from [0] = '+') u = s;
Else sscanf (from, "% d", & u );
If (to [0] = '-') v = t;
Else sscanf (to, "% d", & v );
Adde (u, v, dat, inf );
In [u]-= dat, in [v] + = dat;
}
Build ();
F1 = max_f (ss, tt );
P = yong;
Adde (t, s, 0, inf );
F2 = max_f (ss, tt );
If (f1 + f2! = Sum) printf ("impossible \ n ");
Else printf ("% d \ n", e [p ^ 1]. f );
}
Return 0;
}
/*
Hdu 3157
Poj 3801
A circuit board with N wiring bars (Number 1 ~ N) There are two power supply terminals +-
Then the terminal and minimum current of M parts are given.
Find an impossible output if the total current that can make all parts work normally is not
It is actually a problem of having a source sink with the upper and lower bounds of the smallest stream.
The biggest stream problem with upstream and downstream sources is:
1. Create an additional network
2. Find the maximum stream for the ss and tt (if the ss and tt are full streams, there is a solution)
3. If there is a solution, find the maximum stream for s and t.
The problem of the source sink with the smallest upstream and downstream streams is:
1. Construct an additional network (without adding [t, s] edges)
2. Find the maximum stream for ss and tt
3. Add the [t, s] edge
4. Find the maximum stream for ss and tt
5. If the ss and tt streams are full, the [t, s] traffic is the minimum flow.
Most of the Code is extracted from other questions, and the comments are messy.
*/
# Include <stdio. h>
# Include <string. h>
# Define inf 0x7fffffff
Struct edge // edge
{
Int u, v, f, next, B, c;
} E [1, 1500];
Int head [70], in [70], s, t, ss, tt, yong, sum;
Int n, m;
Void ini ()
{
Memset (head,-1, sizeof (head ));
Yong = 0;
Memset (in, 0, sizeof (in ));
S = 0, t = n + 1, ss = t + 1, tt = ss + 1; // arrangement of node numbers
Sum = 0;
}
Void adde (int from, int to, int xia, int shang) // Edge Addition
{// Edge adding
E [yong]. u = from, e [yong]. v = to, e [yong]. f = shang-xia, e [yong]. B = xia, e [yong]. c = shang;
E [yong]. next = head [from], head [from] = yong ++;
// Add its backend
E [yong]. u = to, e [yong]. v = from, e [yong]. f = 0, e [yong]. B = xia, e [yong]. c = shang;
E [yong]. next = head [to], head [to] = yong ++;
}
Void build ()
{
Int I;
For (I = 0; I <= t; ++ I)
{
If (in [I]> 0)
Adde (ss, I, 0, in [I]);
Else
{
Adde (I, tt, 0,-in [I]);
Sum + = (-in [I]);
}
}
}
Int d [1000], num [1000];
Int min (int a, int B) {return a <B? A: B ;}
Int sap_gap (int u, int f, int s, int t) // recursive sap
{
If (u = t)
Return f;
Int I, v, mind = t, last = f, cost;
For (I = head [u]; I! =-1; I = e [I]. next)
{
V = e [I]. v;
Int flow = e [I]. f;
If (flow> 0) // when writing a reference template, the flow is written as f
{
If (d [u] = d [v] + 1)
{
Cost = sap_gap (v, min (last, flow), s, t );
E [I]. f-= cost;
E [I ^ 1]. f + = cost;
Last-= cost;
If (d [s]> = t + 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 [s] = t + 1;
D [u] = mind + 1;
++ Num [d [u];
}
Return f-last;
}
Int max_f (int s, int t)
{
Int f = 0;
Memset (d, 0, sizeof (d ));
Memset (num, 0, sizeof (num ));
For (num [s] = t + 1; d [s] <t + 1 ;)
F + = sap_gap (s, inf, s, t );
Return f;
}
Int main ()
{
Int I, dat, u, v, f1, f2, p;
Char from [10], to [10];
While (scanf ("% d", & n, & m), n + m)
{
Ini ();
For (I = 1; I <= m; ++ I)
{
Scanf ("% s % d", from, to, & dat );
If (from [0] = '+') u = s;
Else sscanf (from, "% d", & u );
If (to [0] = '-') v = t;
Else sscanf (to, "% d", & v );
Adde (u, v, dat, inf );
In [u]-= dat, in [v] + = dat;
}
Build ();
F1 = max_f (ss, tt );
P = yong;
Adde (t, s, 0, inf );
F2 = max_f (ss, tt );
If (f1 + f2! = Sum) printf ("impossible \ n ");
Else printf ("% d \ n", e [p ^ 1]. f );
}
Return 0;
} Author: qq172108805