此题纯粹最大流没有变形,关键看懂英文
此题是网络流最大流关键是构图和sscanf的运用。此题是多起点多汇点。处理这类问题应该建立超级原点和超级汇点,原来的源点容量和汇点容量处理成超级源点到个源点的容量,各汇点的容量处理为汇点到超级汇点的容量
Time Limit: 2000MS | Memory Limit: 32768K | |
Total Submissions: 17996 | Accepted: 9509 |
Description
An example is in figure 1. The label x/y of power station u shows that p(u)=x and 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 the network but the value of Con cannot exceed 6.
Input
Output
Sample Input
<span style="font-size: 12px;">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</span>
Sample Output
<span style="font-size: 12px;">15 6</span>
Hint
Source
翻译:一个电网由电力运输线连接的节点(发电站,消费者和中转)。一个节点u可提供数额s(U)>=0电力,可能会产生数额为0<= P(U)<= Pmax(U)的电力,可能会消耗数额0<= C(U) <= MIN(s(U),Cmax(U))的电力,并可能传递的数额D(U)=s(U)+ P(U)-C(U)的电力。以下限制适用于:C(U)= 0的任何电站,P(U)=0的任何消费者,P(U)= C(U)= 0的任何中转站。有至多有一个从节点u到节点v的净电力运输线(U,V),它输送的数额0<= L(U,V)<= Lmax的(U,V)电源传递由u到V.让CON=Σuc(U)是净消耗的功率。问题是要计算最大值的CON。
一个例子是在图1。标号x/y电站ü显示了:P(U)= x和Pmax(U)= Y。标签的x / y的消费者ü显示,C(U)= X和Cmax(U)= Y。电力运输线的X / Y(U,V)的标签显示了。l(U,V)= x和Lmax的(U,V)=y。消耗的功率是CON= 6。请注意,有网络的其他可能的状态,但CON值不能超过6。
有几个数据输入集。每个数据集编码一个电源网络。它开始四个整数:0<= N<= 100(节点),0 <= NP<= N(电站),0<= NC<= N(消费者),0<= M <= N^ 2 (电力运输线)y。接下来m个数据三个数(U,V)Z,U和V是节点标识符(从0开始)且0<= Z <= 1000 Lmax的值(U,V)。按照NP双峰(U)Z,其中u是一个发电站和0的标识符<= Z<= 10000 Pmax(U)的价值。数据集结束NC两个数(U)z,其中u是消费者和0的标识符<= Z<= 10000的Cmax值(U)。所有输入的数字都是整数。除外(U,V)Z三胞胎(U)Z双峰,其中不包含空格,空格可以发生自由输入。输入数据的一个文件结束与终止,是正确的。
#include<iostream>
using namespace std;
#define UMAX 201
int c[UMAX][UMAX];
int n,m;
int EK(int s,int t)
{
int p,q,queue[UMAX],u,v,pre[UMAX],flow=0,aug;
while(true)
{
memset(pre,-1,sizeof(pre));
for(queue[p=q=0]=s;p<=q;p++)
{
u=queue[p];
for(v=0;v<n+2&&pre[t]<0;v++)
if(c[u][v]>0&&pre[v]<0)
pre[v]=u,queue[++q]=v;
if(pre[t]>=0)break;
}
if(pre[t]<0)break;
aug=0x7fffffff;
for(u=pre[v=t];v!=s;v=u,u=pre[u])
if(c[u][v]<aug)aug=c[u][v];
for(u=pre[v=t];v!=s;v=u,u=pre[u])
c[u][v]-=aug,c[v][u]+=aug;
flow+=aug;
}
return flow;
}
int main()
{
int i,a,b,va;
int np,nc;
char ss[50];
char ch;
while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
{
memset(c,0,sizeof(c));
for(i=0;i<m;i++)
{
scanf("%s",ss);
sscanf(ss,"(%d,%d)%d",&a,&b,&va);
c[a+1][b+1]=va;
}
for(i=0;i<np;i++)
{
scanf("%s",ss);
sscanf(ss,"(%d)%d",&a,&b);
c[0][a+1]=b;
}
for(i=0;i<nc;i++)
{
scanf("%s",ss);
sscanf(ss,"(%d)%d",&a,&b);
c[a+1][n+1]=b;
}
printf("%d\n",EK(0,n+1));
}
return 0;
}