最大流。每个结点也给了容量,这样要求每条边的都要比结点容量小或相等。
用邻接表实现的,注意要记录反向边在邻接表中的位置,同时在EK算法中也要记录父亲结点中边的位置。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define MAXN 105
//ios::sync_with_stdio(false);
using namespace std;
int N;
int r[MAXN],prev[MAXN],pree[MAXN];
struct Edge
{
int from,to,cap,rev,flow;
Edge(int a,int b,int c,int d):from(a),to(b),cap(c),rev(d),flow(0) {}
};
vector<Edge> gl[MAXN];
void add_edge(int from,int to,int cap)
{
gl[from].push_back(Edge(from,to,cap,gl[to].size()));
gl[to].push_back(Edge(to,from,0,gl[from].size()-1));
}
void Init()
{
for(int i=0; i<=N+1; ++i) gl[i].clear();
memset(pree,0,sizeof(pree));
memset(prev,0,sizeof(prev));
memset(r,0,sizeof(r));
}
int max_flow(int s,int t)
{
int d[MAXN],f=0;
while(1)
{
memset(d,0,sizeof(d));
d[s]=INF;
queue<int> que;
que.push(s);
while(!que.empty())
{
int q=que.front();
que.pop();
for(int i=0; i<gl[q].size(); ++i)
{
Edge e=gl[q][i];
if(!d[e.to]&&e.flow<e.cap)
{
d[e.to]=min(d[q],e.cap-e.flow);
que.push(e.to);
prev[e.to]=q;
pree[e.to]=i;
}
}
}
if(d[t]==0) return f;
for(int i=t; i!=s; i=prev[i])
{
int u=prev[i],v=pree[i];
gl[u][v].flow+=d[t];
gl[i][gl[u][v].rev].flow-=d[t];
}
f+=d[t];
}
}
int main()
{
while(scanf("%d",&N)!=EOF)
{
Init();
for(int i=1; i<=N; ++i)
scanf("%d",&r[i]);
int T;
scanf("%d",&T);
while(T--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
z=min(z,min(r[x],r[y]));
add_edge(x,y,z);
}
int D,B,t;
scanf("%d%d",&D,&B);
while(D--)
{
scanf("%d",&t);
add_edge(0,t,r[t]);
}
while(B--)
{
scanf("%d",&t);
add_edge(t,N+1,r[t]);
}
printf("%d\n",max_flow(0,N+1));
}
return 0;
}