题目大意:
现在有一个发电站,需要给用户送电。
解释一下输入数据:
总结点数 nodenum 电站数power 用户数consumer 电缆线数link
然后link行,起点-终点 发电量
然后power行,每个电站的产电量
然后consumer行,每个用户的用电量
解题思路:
这道题是最大流的入门题,只是变成了多源多汇。这个模型非常经典,只需要添加一个超级源点和一个超级汇点就变成了普通的最大流模型。
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一个投机取巧就是在读取数据(0,1)20的时候是用的scanf(" (%d%d)%d",&u,&v,&cost);
一般在scanf读入数据的时候是最好不好加入别的字符的,因为可能会造成读入数据出错。因为有字符串的存在,所以在(%d%d)前面加上一个空格符号,如果运行后得不到答案,可以输出一下你输入的数据进行测试,首先要保证输入正确。这里也可以用一个字符串来处理数据(但是比较麻烦了);
用的算法还是那个最大流增广路的算法,这个模板是个好东西。。。。
加入了一个超级源点和超级汇点,因为原来的节点是从0开始的,为了好处理,我们让每个节点+1,让它节点变成是从1开始的,又因为我们自己加入了一个超级源点,所以每个节点又+1(超级源点就是1),那么超级汇点就是总的节点个数了。
#include<stdio.h>
#include<queue>
#include<string.h>
#define inf 1<<28
#define min(a,b) a<b?a:b
using namespace std;
int start,end;
int map[105][105];
int flow[105];
int path[105];
int bfs()
{
memset(path,-1,sizeof(path));
int i,u;
queue<int>Q;
path[start]=0;
flow[start]=inf;
Q.push(start);
while(!Q.empty())
{
u=Q.front();
Q.pop();
if(u==end) break;
for(i=start;i<=end;i++)
{
if(i!=start && path[i] == -1 && map[u][i])
{
flow[i]=min(flow[u],map[u][i]);
path[i]=u;
Q.push(i);
}
}
}
if(path[end]==-1)return -1;
return flow[end];
}
int Edmords_Karp()
{
int max_flow=0,ff,now,pre;
memset(flow,0,sizeof(flow));
while((ff=bfs())!=-1)
{
max_flow+=ff;
now=end;
while(now != start)
{
pre=path[now];
map[pre][now]-=ff;
map[now][pre]+=ff;
now=pre;
}
}
return max_flow;
}
int main()
{
int power,consumer,link,u,v,num,cost;
int i,j;
while(~scanf("%d%d%d%d",&num,&power,&consumer,&link))
{
num=num+2;
memset(map,0,sizeof(map));
for(i=0;i<link;i++)
{
scanf(" (%d,%d)%d",&u,&v,&cost);
u+=2;
v+=2;
map[u][v]+=cost;
}
for(i=0;i<power;i++)
{
scanf(" (%d)%d",&u,&cost);
u+=2;
map[1][u]+=cost;
}
for(i=0;i<consumer;i++)
{
scanf(" (%d)%d",&v,&cost);
v+=2;
map[v][num]+=cost;
}
start=1;
end=num;
int res=Edmords_Karp();
printf("%d\n",res);
}
return 0;
}