最大流的模板题,直接用EK算法。。XX城市设定0,YY城市为n+1。还有一点要注意的是在求最小的残量的是还要看每个顶点容量。。
#include<stdio.h> #include<string.h> #include<iostream> #include<queue> #include<algorithm> using namespace std; const int inf=99999999; const int N=110; int f[N],a[N],cap[N][N],flow[N][N],p[N]; using namespace std; int n; int F; int s,t; void EK_() { queue<int>q; memset(flow,0,sizeof(flow)); for(;;) { memset(a,0,sizeof(a)); q.push(s); a[s]=inf; while(!q.empty()) { int u=q.front(); q.pop(); for(int v=0;v<=n+1;v++) { if(!a[v]&&cap[u][v]>flow[u][v]&&flow[u][v]<f[u]&&flow[u][v]<f[v])//看当前流量是否小于顶点的容量 { p[v]=u; q.push(v); a[v]=min(a[u],cap[u][v]-flow[u][v]); a[v]=min(a[v],f[u]-flow[u][v]); a[v]=min(a[v],f[v]-flow[u][v]);//在边之间的容量和顶点之间的容量求一个最小值作为最小的残量 } } } if(a[t]==0) break; for(int u=t;u!=s;u=p[u]) { flow[p[u]][u]+=a[t]; flow[u][p[u]]-=a[t]; } F+=a[t]; } } int main() { while(scanf("%d",&n)!=EOF) { s=0,t=n+1; F=0; for(int i=1;i<=n;i++) { scanf("%d",&f[i]); } int m; scanf("%d",&m); int aa,b,c; memset(cap,0,sizeof(cap)); while(m--) { scanf("%d %d %d",&aa,&b,&c); cap[aa][b]=c; } int B,D; scanf("%d %d",&B,&D); int x; for(int i=0;i<B;i++) { scanf("%d",&x); cap[0][x]=inf; } for(int i=0;i<D;i++) { scanf("%d",&x); cap[x][n+1]=inf; } f[0]=f[n+1]=inf; EK_(); printf("%d ",F); } return 0; }