經典最大流問題,需要將題中的多源點多匯點最大流問題轉化爲單源單匯。
源點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;
}