水题,难的的1A。。。
网络流SAP,增加一个超级源和一个超级汇,而发电站的最大发电量和用电站的最大用电量分别记为从超级源到发电站的最大流量和用电站到超级汇的最大流量。
//428K 469MS #include<iostream> using namespace std; const int inf = 0x7fffffff; const int MAXN = 210; const int MAXM = MAXN*MAXN; int map[MAXN][MAXN]; int dis[MAXN]; int queue[MAXM]; int bef[MAXN]; int num[MAXN]; void set_dis(int end) { int top(0),base(0); memset(dis,-1,sizeof(dis)); memset(num,0,sizeof(num)); queue[top++] = end; dis[end]=0;num[0] = 1; while(top!=base) { int pre = queue[base++]; for(int i=end-1;i!=0;i--) { if(dis[i] != -1 || map[i][pre] == 0) continue; dis[i] = dis[pre]+1; queue[top++] = i; num[dis[i]]++; } } } int cmp(int x,int y) { if(x<y) return x; return y; } int remark(int n,int a) { int tmp=inf; for(int i=1;i!=n+1;i++) if(map[a][i]!=0&&dis[i]>=0) tmp=cmp(tmp,dis[i]+1); if(tmp==inf) tmp=n; return tmp; } int SAP(int n,int s) { int j,a = s;int flow(0); memset(bef,-1,sizeof(bef)); while(dis[s]<n) { for(j=1;j!=n+1;j++) { if(map[a][j]>0&&dis[a]-1==dis[j]) { break; } } if(j<=n) { bef[j] = a;a = j; if(a==n) { int i = n,max(inf); while(bef[i]!=-1) { max = cmp(max,map[bef[i]][i]); i = bef[i]; } i = n; while(bef[i]!=-1) { map[bef[i]][i]-=max; map[i][bef[i]]+=max; i = bef[i]; } flow+=max;a=s; } } else { int x = remark(n,a); num[x]++;num[dis[a]]--; if(num[dis[a]]==0) return flow;//间隙优化 gap dis[a]=x; if(a!=s) a=bef[a]; } } return flow; } int main() { //cout<<inf<<endl; int n,np,nc,m; while(cin>>n>>np>>nc>>m) { memset(map,0,sizeof(map)); n+=2; while(m--) { char c1,c2,c3;int a,b,c; cin>>c1>>a>>c2>>b>>c3>>c; if(a==b) continue; map[a+2][b+2]+=c; } while(np--) { char c1,c2;int a,b; cin>>c1>>a>>c2>>b; map[1][a+2]+=b; } while(nc--) { char c1,c2;int a,b; cin>>c1>>a>>c2>>b; map[a+2][n]+=b; } set_dis(n); cout<<SAP(n,1)<<endl; } return 0; }