Power Network之网络流解题报告

Power Network

Time Limit: 2000MS

 

Memory Limit: 32768K

Total Submissions: 20220

 

Accepted: 10639

Description

A power network consists of nodes (power stations,consumers and dispatchers) connected by power transport lines. A node u may besupplied with an amount s(u) >= 0 of power, may produce an amount 0 <=p(u) <= pmax(u) of power, may consume an amount 0 <= c(u)<= min(s(u),cmax(u)) of power, and may deliver an amountd(u)=s(u)+p(u)-c(u) of power. The following restrictions apply: c(u)=0 for anypower station, p(u)=0 for any consumer, and p(u)=c(u)=0 for any dispatcher.There is at most one power transport line (u,v) from a node u to a node v inthe net; it transports an amount 0 <= l(u,v) <= lmax(u,v) ofpower delivered by u to v. Let Con=Σuc(u) be the power consumed inthe net. The problem is to compute the maximum value of Con.


An example is in figure 1. The label x/y of power station u shows that p(u)=xand pmax(u)=y. The label x/y of consumer u shows that c(u)=x and cmax(u)=y.The label x/y of power transport line (u,v) shows that l(u,v)=x and lmax(u,v)=y.The power consumed is Con=6. Notice that there are other possible states of thenetwork but the value of Con cannot exceed 6.

Input

There are several data sets in the input. Each data setencodes a power network. It starts with four integers: 0 <= n <= 100(nodes), 0 <= np <= n (power stations), 0 <= nc <= n (consumers),and 0 <= m <= n^2 (power transport lines). Follow m data triplets (u,v)z,where u and v are node identifiers (starting from 0) and 0 <= z <= 1000is the value of lmax(u,v). Follow np doublets (u)z, where u is theidentifier of a power station and 0 <= z <= 10000 is the value of pmax(u).The data set ends with nc doublets (u)z, where u is the identifier of aconsumer and 0 <= z <= 10000 is the value of cmax(u). Allinput numbers are integers. Except the (u,v)z triplets and the (u)z doublets,which do not contain white spaces, white spaces can occur freely in input.Input data terminate with an end of file and are correct.

Output

For each data set from the input, the program prints onthe standard output the maximum amount of power that can be consumed in thecorresponding network. Each result has an integral value and is printed fromthe beginning of a separate line.

Sample Input

2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20

7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7

         (3,5)2(3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5

         (0)5 (1)2(3)2 (4)1 (5)4

Sample Output

15

6

Hint

The sample input contains two data sets. The first dataset encodes a network with 2 nodes, power station 0 with pmax(0)=15 andconsumer 1 with cmax(1)=20, and 2 power transport lines with lmax(0,1)=20 andlmax(1,0)=10. The maximum value of Con is 15. The second data set encodes thenetwork from figure 1.

Source

SoutheasternEurope 2003

 

 

 

题目大意:

       本题描述比较混乱,前面一大堆废话,变量命名又比较多,极易混乱,其实该题就是常规的网络流多源多汇问题。题目说有若干个供电站供一些居民使用。

其中涉及到的可用变量包括,总共有n个节点,其中有发电站np个、用户nc个和调度器n-np-nc个三种节点,每个发电站有一个最大发电量,每个用户有个最大接受电量,现在有m条有向边,边有一个最大的流量代表,最多可以流出这么多电,现在从发电站发电到用户,问最多可以发多少电。

解题思路:

一般做到的都是单源单汇型,这里我们可以将发电站看成源点,用户看成汇点,也就是说可以在前后分别增加一个节点,前面的节点指向所有的源点(即供电站),后面的点指向居民,如此建立成单源单汇,求最大流就可以了。所要注意的是所建立的单一供电站和居民的指向由原输入节点各值获得。

代码如下

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#define N 105
#define INF 100000
#define Min(x,y) x<y?x:y
using namespace std;
int map[N][N];
int flow[N][N];
int a[N];
int p[N];
int n,np,nc,m;

int max_flow(int s,int t)
{
	queue <int> q;
	int ans,u,v;
	ans=0;
	memset(flow,0,sizeof(flow));
	while(1)
	{
		memset(a,0,sizeof(a));
		memset(p,0,sizeof(p));
		a[s]=INF;
		q.push(s);
		while(!q.empty())
		{
			u=q.front();
			q.pop();
			for (v=0;v<=n+1;v++)
			{
				if (!a[v] && map[u][v]>flow[u][v])
				{
					p[v]=u;
					q.push(v);
					a[v]=Min(a[u],map[u][v]-flow[u][v]);
				}
			}
		}
		if (a[t]==0) break;
		for (u=t;u!=s;u=p[u])
		{
			flow[p[u]][u]+=a[t];
			flow[u][p[u]]-=a[t];
		}
		ans+=a[t];
	}
	return ans;
}

int main()
{
	int i,x,y,z,a,b;
	char c;
	while(cin>>n>>np>>nc>>m)
	{
		memset(map,0,sizeof(map));
		for(i=0;i<m;i++)
		{
			cin>>c>>x>>c>>y>>c>>z;
			map[x+1][y+1]=+z;
		}
		for(i=0;i<np;i++)
		{
            cin>>c>>a>>c>>b;
            map[0][a+1]+=b;
        }
		for(i=0;i<nc;i++)
		{
            cin>>c>>a>>c>>b;
            map[a+1][n+1]+=b;
        }
		cout<<max_flow(0,n+1)<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值