经典最大流问题,需要将题中的多源点多汇点最大流问题转化为单源单汇。
源点s指向power station,边的权重为相应的power station的pmax;
consumer都指向汇点t,边权为相应的consumer的cmax;
采用Edmonds-Karps耗时有点大,借助scanf才能勉强在1s内跑完!待学习了压入与重标记算法后重写代码。
#include <iostream>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std;
int n, np, nc, m;
int s, t;
vector<vector<int> > links;
vector<int> path, flow;
int MaxFlow()
{
int maxFlow = 0;
while( true )
{
path.assign(n + 2, 0);
path[s] = s;
flow.assign(n + 2, 0);
flow[s] = 0xffff;
queue<int> q;
q.push( s );
while( !q.empty() )
{
int u = q.front();
if( u == t )
break;
q.pop();
for(int j = 0; j < n + 2; ++j)
{
if( !flow[j] && links[u][j] )
{
path[j] = u;
flow[j] = min(flow[u], links[u][j]);
q.push( j );
}
}
}
if( q.empty() )
{
break;
}
maxFlow += flow[t];
for(int v = t; v != s; v = path[v])
{
int u = path[v];
links[u][v] -= flow[t];
links[v][u] += flow[t];
}
}
return maxFlow;
}
int main()
{
while( cin >> n >> np >> nc >> m )
{
links.clear();
links.resize( n + 2 );
for(int i = 0; i < links.size(); ++i)
links[i].assign(n+2, 0);
s = n ;
t = n + 1;
int u, v, w;
char ch;
for(int i = 0; i < m; ++i)
{
scanf(" (%d,%d)%d", &u, &v, &w);
links[u][v] = w;
}
for(int i = 0; i < np; ++i)
{
scanf(" (%d)%d", &v, &w);
links[s][v] = w;
}
for(int i = 0; i < nc; ++i)
{
scanf(" (%d)%d", &u, &w);
links[u][t] = w;
}
cout << MaxFlow() << endl;
}
return 0;
}