最大流。每个结点也给了容量,这样要求每条边的都要比结点容量小或相等。
用邻接表实现的,注意要记录反向边在邻接表中的位置,同时在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; }