<题目链接>
题目大意:
给出 n 个点,其中包括 np个发电站,nc 个消费者, 剩下的全部都是中转点,再给出 这些点中的m 条边,代表这两点间的最大传输电量,并且给出发电站的最大发送电量,以及消费者的最大承受电量,求所有消费者所能得到的最大电量。
解题分析:
本题发电站可以看成源点,消费者看成汇点,由于可能有多个源点和汇点,因此我们可以建立一个超级源点和超级汇点,超级源点与所有发电站直接相连,容量为每个发电站的最大容量,超级汇点与所有消费者相连,容量为每个消费者的最大容量。
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; int n,m,np,nc,s,e; int mpa[110][110]; int vis[110],pre[110]; bool bfs(){ memset(vis,0,sizeof(vis)); memset(pre,0,sizeof(pre)); vis[s]=1; queue<int>q; q.push(s); while(!q.empty()){ int now=q.front(); q.pop(); if(now==e)return true; for(int i=0;i<=n+1;i++){ if(!vis[i]&&mpa[now][i]){ q.push(i); vis[i]=1; pre[i]=now; } } } return false; } int Max_flow(){ int ans=0; while(true){ if(!bfs())return ans; int mn=0x3f3f3f3f; for(int i=e;i!=s;i=pre[i]){ mn=min(mn,mpa[pre[i]][i]); } for(int i=e;i!=s;i=pre[i]){ mpa[pre[i]][i]-=mn; mpa[i][pre[i]]+=mn; } ans+=mn; } } /*--以上是Ek算法模板--*/ int main(){ while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){ memset(mpa,0,sizeof(mpa)); for(int i=1;i<=m;i++){ int a,b,c; /* scanf("%s",ss); sscanf(ss,"(%d,%d)%d",&a,&b,&c); map[a][b]=c; //也可以用这种方法输入 */ while(getchar()!='('); //注意这里的输入格式,也可以用cin简化输入 scanf("%d,%d)%d",&a,&b,&c); mpa[a][b]+=c; } while(np--){ int a,b; while(getchar()!='('); scanf("%d)%d",&a,&b); mpa[n][a]=b; } while(nc--){ int a,b; while(getchar()!='('); scanf("%d)%d",&a,&b); mpa[a][n+1]=b; } s=n,e=n+1; printf("%d\n",Max_flow()); } return 0; }
2018-09-29