POJ 1459 Power Network
多源点汇点的网络流最大流问题。
注意题目要求顶点编号从0开始。我是用SAP算法来做的,用时766ms;EdmondsKarp算法用时1610ms。
以下是我的代码:
注意题目要求顶点编号从0开始。我是用SAP算法来做的,用时766ms;EdmondsKarp算法用时1610ms。
以下是我的代码:
#include
<
iostream
>
#include < sstream >
#include < string >
#include < queue >
#include < algorithm >
#include < cstdio >
#include < cstring >
#include < cctype >
using namespace std;
const int kMaxn( 107 );
const int kInf( 0x7f7f7f7f );
int n,np,nc,m,s,t,c[kMaxn][kMaxn];
int maxflow,f[kMaxn][kMaxn];
void SAP()
{
int d[kMaxn],num[kMaxn],p[kMaxn];
memset(f, 0 ,kMaxn * kMaxn * sizeof ( int ));
memset(d, 0x7f ,kMaxn * sizeof ( int ));
memset(num, 0 ,kMaxn * sizeof ( int ));
queue < int > q;
d[t] = 0 ;
num[ 0 ] ++ ;
q.push(t);
while ( ! q.empty())
{
int v(q.front());q.pop();
for ( int u = 0 ;u < n;u ++ )
if (d[u] >= n && c[u][v] > f[u][v])
{
d[u] = d[v] + 1 ;
num[d[u]] ++ ;
q.push(u);
}
}
maxflow = 0 ;
int u(s),v;
while (d[s] < n)
{
v =- 1 ;
for ( int i = 0 ;i < n;i ++ )
if (c[u][i] > f[u][i] && d[u] == d[i] + 1 )
{v = i; break ;}
if (v !=- 1 )
{
p[v] = u;u = v;
if (u == t)
{
int add(kInf);
for (u = t;u != s;u = p[u])
add = min(add,c[p[u]][u] - f[p[u]][u]);
maxflow += add;
for (u = t;u != s;u = p[u])
{
f[p[u]][u] += add;
f[u][p[u]] -= add;
}
}
}
else
{
num[d[u]] -- ;
if ( ! num[d[u]])
return ;
d[u] = n;
for (v = 0 ;v < n;v ++ )
if (c[u][v] > f[u][v])
d[u] = min(d[u],d[v] + 1 );
num[d[u]] ++ ;
if (u != s)
u = p[u];
}
}
}
int main()
{
while (scanf( " %d%d%d%d " , & n, & np, & nc, & m) == 4 )
{
s = n;
t = n + 1 ;
n += 2 ;
memset(c, 0 ,kMaxn * kMaxn * sizeof ( int ));
for ( int i = 1 ;i <= m;i ++ )
{
string in ;
cin >> in ;
for ( int j = 0 ;j < in .size();j ++ )
if ( ! isdigit( in [j]))
in [j] = ' ' ;
istringstream sin( in );
int u,v,w;
sin >> u >> v >> w;
c[u][v] += w;
}
for ( int i = 1 ;i <= np;i ++ )
{
string in ;
cin >> in ;
for ( int j = 0 ;j < in .size();j ++ )
if ( ! isdigit( in [j]))
in [j] = ' ' ;
istringstream sin( in );
int u,v;
sin >> u >> v;
c[s][u] += v;
}
for ( int i = 1 ;i <= nc;i ++ )
{
string in ;
cin >> in ;
for ( int j = 0 ;j < in .size();j ++ )
if ( ! isdigit( in [j]))
in [j] = ' ' ;
istringstream sin( in );
int u,v;
sin >> u >> v;
c[u][t] += v;
}
SAP();
printf( " %d\n " ,maxflow);
}
return 0 ;
}
#include < sstream >
#include < string >
#include < queue >
#include < algorithm >
#include < cstdio >
#include < cstring >
#include < cctype >
using namespace std;
const int kMaxn( 107 );
const int kInf( 0x7f7f7f7f );
int n,np,nc,m,s,t,c[kMaxn][kMaxn];
int maxflow,f[kMaxn][kMaxn];
void SAP()
{
int d[kMaxn],num[kMaxn],p[kMaxn];
memset(f, 0 ,kMaxn * kMaxn * sizeof ( int ));
memset(d, 0x7f ,kMaxn * sizeof ( int ));
memset(num, 0 ,kMaxn * sizeof ( int ));
queue < int > q;
d[t] = 0 ;
num[ 0 ] ++ ;
q.push(t);
while ( ! q.empty())
{
int v(q.front());q.pop();
for ( int u = 0 ;u < n;u ++ )
if (d[u] >= n && c[u][v] > f[u][v])
{
d[u] = d[v] + 1 ;
num[d[u]] ++ ;
q.push(u);
}
}
maxflow = 0 ;
int u(s),v;
while (d[s] < n)
{
v =- 1 ;
for ( int i = 0 ;i < n;i ++ )
if (c[u][i] > f[u][i] && d[u] == d[i] + 1 )
{v = i; break ;}
if (v !=- 1 )
{
p[v] = u;u = v;
if (u == t)
{
int add(kInf);
for (u = t;u != s;u = p[u])
add = min(add,c[p[u]][u] - f[p[u]][u]);
maxflow += add;
for (u = t;u != s;u = p[u])
{
f[p[u]][u] += add;
f[u][p[u]] -= add;
}
}
}
else
{
num[d[u]] -- ;
if ( ! num[d[u]])
return ;
d[u] = n;
for (v = 0 ;v < n;v ++ )
if (c[u][v] > f[u][v])
d[u] = min(d[u],d[v] + 1 );
num[d[u]] ++ ;
if (u != s)
u = p[u];
}
}
}
int main()
{
while (scanf( " %d%d%d%d " , & n, & np, & nc, & m) == 4 )
{
s = n;
t = n + 1 ;
n += 2 ;
memset(c, 0 ,kMaxn * kMaxn * sizeof ( int ));
for ( int i = 1 ;i <= m;i ++ )
{
string in ;
cin >> in ;
for ( int j = 0 ;j < in .size();j ++ )
if ( ! isdigit( in [j]))
in [j] = ' ' ;
istringstream sin( in );
int u,v,w;
sin >> u >> v >> w;
c[u][v] += w;
}
for ( int i = 1 ;i <= np;i ++ )
{
string in ;
cin >> in ;
for ( int j = 0 ;j < in .size();j ++ )
if ( ! isdigit( in [j]))
in [j] = ' ' ;
istringstream sin( in );
int u,v;
sin >> u >> v;
c[s][u] += v;
}
for ( int i = 1 ;i <= nc;i ++ )
{
string in ;
cin >> in ;
for ( int j = 0 ;j < in .size();j ++ )
if ( ! isdigit( in [j]))
in [j] = ' ' ;
istringstream sin( in );
int u,v;
sin >> u >> v;
c[u][t] += v;
}
SAP();
printf( " %d\n " ,maxflow);
}
return 0 ;
}