最小费用最大流模板

匿名 (未验证) 提交于 2019-12-03 00:05:01
 1 #include<cstdio>  2 #include<queue>  3 #include<cstring>  4 #include<queue>  5 #include<algorithm>  6 #define INF 2147483647  7 #define LL long long  8 using namespace std;  9 queue<int>q; 10 int n,m,m1,t1,m2,t2,num=-1,st,ed; 11 struct node{ 12     int x,y,c,d,next; 13 }G[100000]; 14 int b[100000],head[100000],pre[100000],pos[100000],max_flow[100000]; 15 LL dis[100000]; 16 bool vis[100000]; 17 void ins(int x,int y,int c,int d) 18 { 19     G[++num].x=x;G[num].y=y;G[num].c=c;G[num].d=d;G[num].next=head[x];head[x]=num; 20     G[++num].x=y;G[num].y=x;G[num].c=0;G[num].d=-d;G[num].next=head[y];head[y]=num; 21 } 22 bool spfa() 23 { 24     memset(vis,true,sizeof(vis)); 25     vis[st]=false; 26     memset(dis,63,sizeof(dis)); 27     dis[st]=0; 28     max_flow[st]=INF; 29     q.push(st); 30     while(!q.empty()){ 31         int x=q.front(); 32         vis[x]=true; 33         q.pop(); 34         for(int i=head[x];i!=-1;i=G[i].next){ 35             int y=G[i].y; 36             if(G[i].c>0&&dis[y]>dis[x]+G[i].d){ 37                 dis[y]=dis[x]+G[i].d; 38                 pos[y]=x; 39                 pre[y]=i; 40                 max_flow[y]=min(max_flow[x],G[i].c); 41                 if(vis[y]){ 42                     q.push(y); 43                     vis[y]=false; 44                 } 45             } 46         } 47     } 48     return dis[ed]<4557430888798830399; 49 } 50 LL flow() 51 { 52     LL ans=0; 53     while(spfa()){ 54         ans+=max_flow[ed]*dis[ed]; 55         for(int i=ed;i!=st;i=pos[i]){ 56             G[pre[i]].c-=max_flow[ed]; 57             G[pre[i]^1].c+=max_flow[ed]; 58         } 59     } 60     return ans; 61 } 62 int main() 63 { 64     int x; 65     scanf("%d",&n); 66     st=0,ed=2*n+1; 67     memset(head,-1,sizeof(head)); 68     for(int i=1;i<=n;i++){ 69         scanf("%d",&x); 70         ins(st,i,x,0);//每天晚上从起点获得x条脏餐巾 71         ins(i+n,ed,x,0);//每天白天,向汇点提供x条干净的餐巾,流满时表示第i天的餐巾够用 72     } 73     scanf("%d %d %d %d %d",&m,&t1,&m1,&t2,&m2); 74     for(int i=1;i<=n;i++){ 75         if(i+1<=n) ins(i,i+1,INF,0);//每天晚上可以将脏餐巾留到第二天晚上 76         if(i+t1<=n) ins(i,i+n+t1,INF,m1);//每天晚上可以送去快洗部,在地i+t1天早上收到餐巾 77         if(i+t2<=n) ins(i,i+n+t2,INF,m2);//每天晚上可以送去慢洗部,在地i+t2天早上收到餐巾 78         ins(st,i+n,INF,m);//每天早上可以购买餐巾 79     } 80     printf("%lld",flow()); 81 }

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!