-
题意:
简单的说下题意(按输入输出来讲,前面的描述一堆的rubbish,还用来误导人),给你n个点,其中有np个是能提供电力的点,nc个是能消费电力的点,剩下的点(n-np-nc)是中转战即不提供电力也不消费电力,点与点之间是有线路存在的,有m条线路,每条线路有最多运载限定。
前4个数据就是有n个点,np个供电点,nc个消费点,m条线路,接来题目先给出的是m条线路的数据,(起点,终点)最多运载量,然后是np个供电点的数据(供电点)最多供电量,接着就是nc个消费点的数据(消费点)最多消费电量。
题目要我们求出给定的图最大能消费的总电量(就是求最大流) -
思路:
供电点有提供功能,那么供电点就可以当成源点,同样消费点有消费功能,可以当成汇点。
由于这题有多个供电点和消费点,我们可以增加两个点,一个超级源点和一个超级汇点。
把所有的供电点都当成是由超级源点提供电量的,所有的消费点都将消费电量转移到超级汇点上,这样就相当于转换成一个基本的网络流求最大流的题。
超级源点与供电点有一条边,边的值为供电点最大能提供的电量,消费点与超级汇点有一条边,边的值为消费点最大能消费的电量。
#include<iostream>
#include<cstdio>
#include<climits>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 105;
const int MAXINT = INT_MAX;
typedef struct
{
int flow; //流量
int capacity; //最大容量值
}Edge;
Edge edge[maxn][maxn];
int vertime; //顶点总数
int nedges; //边的总数
int power_stations; //发电站总数
int consumers; //消费者总数
int maxflow; //最大流
int sp, fp; //标记源点与汇点
int parent[maxn]; //用于bfs寻找路径
int bfs(int start, int _end)
{
int res[maxn];
queue<int> q;
memset(res, 0, sizeof(res));
memset(parent, -1, sizeof(parent));
q.push(start);
res[start] = MAXINT;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int v = 1; v <= vertime; v++)
{
if(!res[v] && edge[u][v].capacity > edge[u][v].flow)
{
q.push(v);
parent[v] = u;
res[v] = min(res[u], edge[u][v].capacity - edge[u][v].flow);
}
}
if(u == _end)
break;
}
return res[_end];
}
void EdmondsKarp()
{
int tmp;
maxflow = 0;
while(tmp = bfs(sp, fp))
{
for(int i = fp; i!= sp; i = parent[i])
{
edge[parent[i]][i].flow += tmp; //更新正向流
edge[i][parent[i]].flow -= tmp; //更新反向流
}
maxflow += tmp;
}
}
int main()
{
int u, v, w;
char ch;
while(scanf("%d%d%d%d", &vertime, &power_stations, &consumers, &nedges) != EOF)
{
memset(edge, 0, sizeof(edge));
for(int i = 1; i <= nedges; i++) //设置读图从1开始
{
cin >> ch >> u >> ch >> v >> ch >> w;
edge[u+1][v+1].capacity = w;
}
sp = vertime + 1, fp = vertime + 2, vertime += 2;
for(int i = 1; i <= power_stations; i++) //建立超级源点指向所有的发电站
{
cin >> ch >> v >> ch >> w;
edge[sp][v+1].capacity = w;
}
for(int i = 1; i <= consumers; i++) //建立超级汇点,使所有消费者指向它
{
cin >> ch >> v >> ch >> w;
edge[v+1][fp].capacity = w;
}
EdmondsKarp();
printf("%d\n", maxflow);
}
return 0;
}