//网络流——最大流 //通过添加虚源点和虚汇点构图,转化为从源点到汇点的最短路 #include<iostream> #include<cstring> #include<queue> #define INF 2000000000 using namespace std; int n,np,nc,m; int x,y,c,p,f,maxflow,st,ed,u,v; int cap[105][105],flow[105][105]; int rflow[105],pre[105]; int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d%d%d",&n,&np,&nc,&m) != EOF) { maxflow = 0; memset(cap,0,sizeof(cap)); memset(flow,0,sizeof(flow)); st = n; ed = n + 1; for(int i = 0;i < m;++i) { scanf("%*[^(](%d,%d)%d",&x,&y,&c);//神奇的输入方式,参考poj上的discuss才知道的,还可以通过sscanf来实现 cap[x][y] = c; } for(int i = 0;i < np;++i) { scanf("%*[^(](%d)%d",&p,&f); cap[st][p] = f;//添加虚源点,将源点和发电站相连 } for(int i = 0;i < nc;++i) { scanf("%*[^(](%d)%d",&c,&f); cap[c][ed] = f;//添加虚汇点,将用电器和汇点相连 } for(;;)//最大流模板 { queue<int> q; memset(rflow,0,sizeof(rflow)); rflow[st] = INF; q.push(st); while(!q.empty()) { u = q.front(); q.pop(); for(v = 0;v <= ed;++v) { if(!rflow[v] && cap[u][v] > flow[u][v])//残留量未被标记并且容量大于当前流量,则可拓展该结点 { rflow[v] = min(rflow[u],cap[u][v] - flow[u][v]);//更新最小结点残量值 pre[v] = u;//前驱指针 q.push(v); } } } if(rflow[ed] == 0) break;//汇点未被标记,说明残量网络中找不到增广路,跳出 for(u = ed;u != st;u = pre[u])//从汇点靠前驱指针往回遍历增广路 { flow[pre[u]][u] += rflow[ed];//更新正向当前流量 flow[u][pre[u]] -= rflow[ed];//更新反向当前流量 } maxflow += rflow[ed];//更新最大流 } printf("%d/n",maxflow); } return 0; }