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 ",ans); 128 } 129 return 0; 130 }