1 #include<cstring>
2 #include<cstdio>
3 #define FOR(i,f_start,f_end) for(int i=f_startl;i<=f_end;i++)
4 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr))
5 const int maxn=500;
6 const int maxm=2e4+5;
7 int size;
8 int n;
9 const int inf=0x3f3f3f3f;
10 using namespace std;
11 int head[maxn];
12 void init(){
13 size=0;
14 MS(head,-1);
15 }
16 struct Node{
17 int from,to,cap,next;
18 }edge[maxn];
19 void add(int u,int v,int w){
20 edge[size].from=u;
21 edge[size].to=v;
22 edge[size].cap=w;
23 edge[size].next=head[u];
24 head[u]=size++;
25 edge[size].from=v;
26 edge[size].to=u;
27 edge[size].cap=0;
28 edge[size].next=head[v];
29 head[v]=size++;
30 }
31 int dep[maxn];
32 int bfs(int start,int end){
33 int que[maxn];
34 int front,rear;
35 MS(dep,-1);
36 que[rear++]=start;
37 dep[start]=0;
38 while(front!=rear){
39 int u=que[front++];
40 if(front==maxn)front=0;
41 for(int i=head[u];i!=-1;i=edge[i].next){
42 int v=edge[i].to;
43 if(edge[i].cap>0&&dep[v]==-1){
44 dep[v]=dep[u]+1;
45 que[rear++]=v;
46 if(rear>=maxn)rear=0;
47 if(v==end)return 1;//优化1 找到直接返回
48 }
49 }
50 }
51 return 0;
52
53 }
54 int dinic(int start,int end){
55
56 int res=0;
57 int top;
58 int stack[maxn];//非递归 手写栈
59 int cur[maxn];
60 while(bfs(start,end)){
61 memcpy(cur,head,sizeof(head));//当前弧预备工作
62 int u=start;
63 top=0;
64 while(1){
65 if(u==end){//当找到终点的时候
66 int min=inf;
67 int loc;
68 for(int i=0;i<top;i++){//找到路径里面最小的流量
69 if(min>edge[stack[i]].cap){
70 min=edge[stack[i]].cap;
71 loc=i;//记下最小流量的边 之后的点都不可能到达了
72 }
73 }
74 for(int i=0;i<top;i++){//减流量和加反向边
75 edge[stack[i]].cap-=min;
76 edge[stack[i]^1].cap+=min;
77 }
78 res+=min;
79 top=loc;//退栈顶到那个流量已经清零的边的起点i
80 u=edge[stack[top]].from;
81
82 }
83 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)//当前弧优化如果存在以下情况的时候就可以break进行操作了
84 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])
85 break;
86 if(cur[u]!=-1){//如果有边可以走 那么就把边和点入栈
87 stack[top++]=cur[u];
88 u=edge[cur[u]].to;
89 }
90 else {//如果从栈顶点出发找不到可以增广的路径了,那么如果栈已经空了 那可能就没有可以增广的路径了,而如果栈没有空 那么就退栈继续找
91 if(top==0)break;
92 dep[u]=-1;//因为从u已经找不到可以走的路径了 直接把dep[u]=-1相当于没有点可以可以通过dep[u]+1==dep[edge[i].to]的条件 也就是u以后也入不了栈了
93 u=edge[stack[--top]].from;
94 }
95 }
96 }
97 return res;
98 }
99 int main(){
100 int start,end;
101 int np,nc,m;
102 int u,v,z;
103 while(scanf("%d%d%d%d",&n,&np,&nc,&m)==4){
104 init();
105 while(m--){
106 while(getchar()!='(');
107 scanf("%d,%d)%d",&u,&v,&z);
108 u++,v++;
109 add(u,v,z);
110
111 }
112 while(np--){
113 while(getchar()!='(');
114 scanf("%d)%d",&u,&z);
115 u++;
116 add(0,u,z);
117 }
118 while(nc--){
119 while(getchar()!='(');
120 scanf("%d)%d",&u,&v);
121 u++;
122 add(u,n+1,z);
123 }
124 start=0;
125 end=n+1;
126 int ans=dinic(start,end);
127 printf("%d\n",ans);
128 }
129 return 0;
130 }