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 }
  • 相关阅读:
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Path Sum
    Symmetric Tree
    Solve Tree Problems Recursively
    632. Smallest Range(priority_queue)
    609. Find Duplicate File in System
    poj3159最短路spfa+邻接表
  • 原文地址:https://www.cnblogs.com/pantakill/p/6604666.html
Copyright © 2011-2022 走看看