思路:
最小费用最大流模板题。
用EdmondsKarp,增广时使用SPFA求最短路。
1 #include<queue> 2 #include<cstdio> 3 #include<cctype> 4 #include<cstring> 5 inline int getint() { 6 char ch; 7 while(!isdigit(ch=getchar())); 8 int x=ch^‘0‘; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^‘0‘); 10 return x; 11 } 12 const int E=100000,V=5001; 13 const int inf=0x7fffffff; 14 struct Edge { 15 int from,to,remain,cost; 16 }; 17 Edge e[E]; 18 int g[V][V]={0}; 19 int sz=0; 20 inline void add_edge(const int u,const int v,const int w,const int f) { 21 e[sz]=(Edge){u,v,w,f}; 22 g[u][++g[u][0]]=sz; 23 sz++; 24 } 25 int n,m,s,t; 26 int a[V],p[V],d[V]; 27 bool inq[V]; 28 inline int Augment() { 29 memset(a,0,sizeof a); 30 a[s]=inf; 31 std::queue<int> q; 32 q.push(s); 33 memset(inq,0,sizeof inq); 34 inq[s]=true; 35 for(int i=1;i<=n;i++) { 36 d[i]=(i==s)?0:inf; 37 } 38 while(!q.empty()) { 39 int x=q.front(); 40 q.pop(); 41 inq[x]=false; 42 for(int i=1;i<=g[x][0];i++) { 43 Edge &y=e[g[x][i]]; 44 if(y.remain&&(d[x]+y.cost<d[y.to])) { 45 p[y.to]=g[x][i]; 46 a[y.to]=std::min(a[x],y.remain); 47 d[y.to]=d[x]+y.cost; 48 if(!inq[y.to]) { 49 q.push(y.to); 50 inq[y.to]=true; 51 } 52 } 53 } 54 } 55 return a[t]; 56 } 57 inline std::pair<int,int> EdmondsKarp() { 58 int maxflow=0,mincost=0; 59 while(int flow=Augment()) { 60 for(int i=t;i!=s;i=e[p[i]].from) { 61 e[p[i]].remain-=flow; 62 e[p[i]^1].remain+=flow; 63 } 64 maxflow+=flow; 65 mincost+=d[t]*flow; 66 } 67 return std::make_pair(maxflow,mincost); 68 } 69 int main() { 70 n=getint(),m=getint(),s=getint(),t=getint(); 71 while(m--) { 72 int u=getint(),v=getint(),w=getint(),f=getint(); 73 add_edge(u,v,w,f); 74 add_edge(v,u,0,-f); 75 } 76 std::pair<int,int> MCMF=EdmondsKarp(); 77 printf("%d %d\n",MCMF.first,MCMF.second); 78 return 0; 79 }
时间: 2024-10-12 19:49:17