这题是算法导论上的经典模型,将发电站看成源,用户看成汇,这样就形成了多源多汇网络流模型,直接加一个总的源汇即可。 源到发电站的容量为发电站的容量,用户到汇 的容量为用户容量,直接跑最大流即可。 我的代码: #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int MAX=120; const int oo=0x3f3f3f3f; struct Edge{ int num,ne,cap; }e[2*MAX*MAX]; int pre[MAX],pree[MAX],low[MAX],gap[MAX],cur[MAX],p[MAX]; int dist[MAX]; int n,st,ed,K; int get(){ int ret=0; bool flag=false; char ch; while((ch=getchar())<'0'||ch>'9')if(ch=='-')break; if(ch=='-')flag=true;else ret=ch-'0'; while((ch=getchar())>='0'&&ch<='9')ret=ret*10+ch-'0'; return flag?-ret:ret; } void add(const int& u,const int& v,const int& cap){ e[K].num=v;e[K].cap=cap;e[K].ne=p[u];p[u]=K++; e[K].num=u;e[K].cap=0;e[K].ne=p[v];p[v]=K++; } int sap(){ int ret=0; bool done; memset(dist,0,sizeof(dist)); memset(gap,0,sizeof(gap)); memset(low,0,sizeof(low)); for(int i=0;i<n;i++)cur[i]=p[i]; low[st]=oo; int u=st; while(dist[u]<n){ done=true; for(int i=cur[u];~i;i=e[i].ne){ int v=e[i].num; cur[u]=i; if(e[i].cap&&dist[u]==dist[v]+1){ pre[v]=u;pree[v]=i; low[v]=min(low[u],e[i].cap); u=v; if(u==ed){ do{ e[pree[u]].cap-=low[ed]; e[pree[u]^1].cap+=low[ed]; u=pre[u]; }while(u!=st); ret+=low[ed]; } done=false; break; } } if(done){ gap[dist[u]]--; if(!gap[dist[u]])return ret; dist[u]=n; cur[u]=p[u]; for(int i=p[u];~i;i=e[i].ne){ if(e[i].cap)dist[u]=min(dist[u],dist[e[i].num]+1); } gap[dist[u]]++; if(u!=st)u=pre[u]; } } return ret; } int main(){ int nn,np,nc,m; char ch; while(~scanf("%d%d%d%d",&nn,&np,&nc,&m)){ n=nn+2; st=nn; ed=nn+1; for(int i=0;i<n;i++)p[i]=-1;K=0; while(m--){ while((ch=getchar())!='('); int u=get(); int v=get(); int w=get(); add(u,v,w); } while(np--){ int u=get(); int w=get(); add(st,u,w); } while(nc--){ int u=get(); int w=get(); add(u,ed,w); } printf("%d/n",sap()); } return 0; }