1. 程式人生 > >洛谷P4015 運輸問題(費用流)

洛谷P4015 運輸問題(費用流)

tar pro next str 流量 mes printf ring ans

傳送門

源點向倉庫連費用$0$,流量為儲量的邊,商店向匯點連費用$0$,流量為需求的邊,然後倉庫向商店連流量$inf$,費用對應的邊,跑個費用流即可

  1 //minamoto
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<queue>
  5 #include<cstring>
  6 #define inf 0x3f3f3f3f
  7 using namespace std;
  8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  9
char buf[1<<21],*p1=buf,*p2=buf; 10 inline int read(){ 11 #define num ch-‘0‘ 12 char ch;bool flag=0;int res; 13 while(!isdigit(ch=getc())) 14 (ch==-)&&(flag=true); 15 for(res=num;isdigit(ch=getc());res=res*10+num); 16 (flag)&&(res=-res); 17
#undef num 18 return res; 19 } 20 const int N=205,M=25005; 21 int ver[M],Next[M],head[N],edge[M],flow[M],tot=1; 22 int dis[N],disf[N],n,m,s,t,ans,Pre[N],last[N],vis[N],x; 23 queue<int> q; 24 inline void add(int u,int v,int e,int f){ 25 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,flow[tot]=f;
26 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=-e,flow[tot]=0; 27 } 28 bool spfa_min(){ 29 memset(dis,0x3f,sizeof(dis)); 30 memset(vis,0,sizeof(vis)); 31 memset(disf,0x3f,sizeof(disf)); 32 q.push(s),dis[s]=0,vis[s]=1,Pre[t]=-1; 33 while(!q.empty()){ 34 int u=q.front();q.pop();vis[u]=0; 35 for(int i=head[u];i;i=Next[i]){ 36 int v=ver[i]; 37 if(flow[i]>0&&dis[v]>dis[u]+edge[i]){ 38 dis[v]=dis[u]+edge[i],Pre[v]=u; 39 last[v]=i,disf[v]=min(disf[u],flow[i]); 40 if(!vis[v]) vis[v]=1,q.push(v); 41 } 42 } 43 } 44 return Pre[t]!=-1; 45 } 46 int dinic_min(){ 47 int maxflow=0,mincost=0; 48 while(spfa_min()){ 49 int u=t; 50 maxflow+=disf[t],mincost+=disf[t]*dis[t]; 51 while(u!=s){ 52 flow[last[u]]-=disf[t]; 53 flow[last[u]^1]+=disf[t]; 54 u=Pre[u]; 55 } 56 } 57 return mincost; 58 } 59 bool spfa_max(){ 60 memset(dis,0xef,sizeof(dis)); 61 memset(vis,0,sizeof(vis)); 62 memset(disf,0x3f,sizeof(disf)); 63 q.push(s),dis[s]=0,vis[s]=1,Pre[t]=-1; 64 while(!q.empty()){ 65 int u=q.front();q.pop();vis[u]=0; 66 for(int i=head[u];i;i=Next[i]){ 67 int v=ver[i]; 68 if(flow[i]>0&&dis[v]<dis[u]+edge[i]){ 69 dis[v]=dis[u]+edge[i],Pre[v]=u; 70 last[v]=i,disf[v]=min(disf[u],flow[i]); 71 if(!vis[v]) vis[v]=1,q.push(v); 72 } 73 } 74 } 75 return Pre[t]!=-1; 76 } 77 int dinic_max(){ 78 int maxflow=0,maxcost=0; 79 while(spfa_max()){ 80 int u=t; 81 maxflow+=disf[t],maxcost+=disf[t]*dis[t]; 82 while(u!=s){ 83 flow[last[u]]-=disf[t]; 84 flow[last[u]^1]+=disf[t]; 85 u=Pre[u]; 86 } 87 } 88 return maxcost; 89 } 90 int main(){ 91 m=read(),n=read(); 92 s=0,t=n+m+1; 93 for(int i=1;i<=m;++i){ 94 int x=read(); 95 add(s,i,0,x); 96 } 97 for(int i=m+1;i<=n+m;++i){ 98 int x=read(); 99 add(i,t,0,x); 100 } 101 for(int i=1;i<=m;++i) 102 for(int j=1;j<=n;++j){ 103 int x=read(); 104 add(i,j+m,x,inf); 105 } 106 printf("%d\n",dinic_min()); 107 for(int i=2;i<=tot;i+=2) flow[i]+=flow[i^1],flow[i^1]=0; 108 printf("%d\n",dinic_max()); 109 return 0; 110 }

洛谷P4015 運輸問題(費用流)