zoukankan      html  css  js  c++  java
  • 【中学高级本-网络流24题】餐巾计划

    把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源ST
    1、从S向每个Xi连一条容量为ri,费用为0的有向边。
    表示第i天还剩ri条餐巾。
    2、从每个YiT连一条容量为ri,费用为0的有向边。
    控制最大流
    3、从S向每个Yi连一条容量为无穷大,费用为p的有向边。
    表示买餐巾
    4、从每个XiXi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。
    表示第i天剩的餐巾可以留给第i+1天。
    5、从每个XiYi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边。
    表示快洗
    6、从每个XiYi+n(i+n<=N)连一条容量为无穷大,费用为s的有向边。
    表示慢洗
    然后就求最小费用最大流就可以了
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 #define inf 1999999999
    15 using namespace std;
    16 struct data{
    17   int nex,to,w,c;
    18 }e[2610];
    19 int head[410],edge=-1,dis[410],vis[410],pre[410];
    20 void add(int from,int to,int w,int c){
    21   e[++edge].nex=head[from];
    22   e[edge].to=to;
    23   e[edge].w=w;
    24   e[edge].c=c;
    25   head[from]=edge;
    26 }
    27 inline int SPFA(int s,int t){
    28   queue<int>q;
    29   q.push(s);
    30   memset(dis,127,sizeof(dis));int zd=dis[0];
    31   memset(vis,0,sizeof(vis));
    32   dis[s]=0,vis[s]=1;
    33   while(!q.empty()){
    34     int u=q.front();q.pop();
    35     vis[u]=0;
    36     for(int i=head[u];i!=-1;i=e[i].nex){
    37       int v=e[i].to;
    38       if(e[i].w>0 && dis[v]>dis[u]+e[i].c){
    39     dis[v]=dis[u]+e[i].c;
    40     pre[v]=i;
    41     if(!vis[v])q.push(v),vis[v]=1;
    42       }
    43     }
    44   }
    45   if(dis[t]==zd) return 0;
    46   else return 1;
    47 }
    48 inline int end(int s,int t){
    49   int ans=0,p=0,sum=inf;
    50   for(int u=t;u!=s;u=e[p^1].to)
    51     p=pre[u],sum=min(sum,e[p].w);
    52   for(int u=t;u!=s;u=e[p^1].to){
    53     p=pre[u];
    54     e[p].w-=sum;
    55     e[p^1].w+=sum;
    56     ans+=e[p].c*sum;
    57   }
    58   return ans;
    59 }
    60 inline int solve(int s,int t){
    61   int flow=0;
    62   while(SPFA(s,t)) flow+=end(s,t);
    63   return flow;
    64 }
    65 int main()
    66 {
    67   freopen("!.in","r",stdin);
    68   freopen("!.out","w",stdout);
    69   memset(head,-1,sizeof(head));
    70   int n,p,k,fk,m,fm,x;
    71   scanf("%d",&n);int s=0,t=2*n+1;
    72   for(int i=1;i<=n;i++)
    73     scanf("%d",&x),add(s,i,x,0),add(i,s,0,0),add(i+n,t,x,0),add(t,i+n,0,0);
    74   scanf("%d%d%d%d%d",&p,&k,&fk,&m,&fm);
    75   for(int i=2;i<=n;i++)
    76     add(i-1,i,inf,0),add(i,i-1,0,0);
    77   for(int i=1;i<=n;i++){
    78     if(i-k>0) add(i-k,i+n,inf,fk),add(i+n,i-k,0,-fk);
    79     if(i-m>0) add(i-m,i+n,inf,fm),add(i+n,i-m,0,-fm);
    80     add(s,n+i,inf,p),add(n+i,s,0,-p);
    81   }
    82   printf("%d",solve(s,t));
    83   return 0;
    84 }
  • 相关阅读:
    多选菜单shell脚本
    获取nginx日志状态码百分比脚本
    Linux内核参数优化
    deploy.sh
    Docker常用命令速查
    Docker架构
    修改Docker默认存储路径
    redis安装与基本使用
    js实现汉字转拼音
    android:Android 6.0+ 权限控制代码封装
  • 原文地址:https://www.cnblogs.com/pantakill/p/6604666.html
Copyright © 2011-2022 走看看