zoukankan      html  css  js  c++  java
  • 【费用流】BZOJ1221-[HNOI2001] 软件开发

    【题目大意】

    某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

    【思路】

    将每一天拆为两个点,左边表示将要去消毒的毛巾,右边表示消毒好的毛巾,进行建图。

    设置一个源点S和汇点T

    ·由源点向每天连一条容量为towel[i],费用为0的边;由每天向汇点连一条容量为towel[i],费用为0的边。

    由于每条毛巾可以用AB方法进行消毒
    ·由i向(i+n)+ta+1连一条容量为INF,费用为fa的边;由i向(i+n)+tb+1连一条容量为INF,费用为fb的边

    由于当天未用完的毛巾可以直接留下给下一天
    ·由源点向i+n连一条容量为INF,费用为f的边

    由于当天的毛巾可以留到第二天再进行清洗
    ·由i向i+1连一条容量为INF,费用为0的边

    因为中间边的容量均为INF,可以保证最大流是满流,这种情况下的最小费用流答案即为最小花费。

    【错误点】

    犯了点零零星星的小错,依然是初始化错误+手残打错,已经写进了注释。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 #include<queue>
      7 #define S 0
      8 #define T 2*n+1
      9 using namespace std;
     10 const int MAXN=2000+100;
     11 const int INF=0x7fffffff;
     12 struct node
     13 {
     14     int to,pos,cap,cost;
     15 };
     16 
     17 vector<node> E[MAXN];
     18 int n,ta,tb,f,fa,fb;
     19 int towel[MAXN];
     20 int pre[MAXN],preedge[MAXN];
     21 
     22 void addedge(int u,int v,int w,int c)
     23 {
     24     E[u].push_back((node){v,E[v].size(),w,c});
     25     E[v].push_back((node){u,E[u].size()-1,0,-c}); 
     26 }
     27 
     28 void init()
     29 {
     30     scanf("%d%d%d%d%d%d",&n,&ta,&tb,&f,&fa,&fb);
     31      for (int i=1;i<=n;i++)
     32      {
     33          scanf("%d",&towel[i]);
     34          
     35          /*将一天拆为两个点, 
     36           由源点向每天连一条容量为towel[i],费用为0的边
     37           由每天向汇点连一条容量为towel[i],费用为0的边*/
     38          addedge(S,i,towel[i],0);
     39          addedge(i+n,T,towel[i],0);
     40          
     41          /*由于每条毛巾可以用AB方法进行消毒
     42         由i向(i+n)+ta+1连一条容量为INF,费用为fa的边 
     43         由i向(i+n)+tb+1连一条容量为INF,费用为fb的边*/
     44         if (i+n+ta+1<=2*n) addedge(i,i+n+ta+1,INF,fa);
     45         if (i+n+tb+1<=2*n) addedge(i,i+n+tb+1,INF,fb);
     46 
     47         /*由于当天未用完的毛巾可以直接留下给下一天
     48         或者当天的毛巾可以留到第二天再进行清洗 
     49         由源点向i+n连一条容量为INF,费用为f的边
     50         由i向i+1连一条容量为INF,费用为0的边*/
     51         addedge(S,i+n,INF,f);
     52         if (i+1<=n) addedge(i,i+1,INF,0);
     53     }
     54 }
     55 
     56 int SPFA()
     57 {
     58     int vis[MAXN],dis[MAXN];
     59     queue<int> que;
     60     memset(vis,0,sizeof(vis));
     61     memset(pre,-1,sizeof(pre));
     62     for (int i=1;i<=T;i++) dis[i]=INF;                      //这里一开始草率地初始化为127,事实上这个值和INF不相等,会导致判断出错 
     63     vis[S]=1;
     64     dis[S]=0;
     65     que.push(S);
     66     while (!que.empty())
     67     {
     68         int head=que.front();que.pop();
     69         vis[head]=0;
     70         for (int i=0;i<E[head].size();i++)                     //这里打成了E[i].size()查了半天才发现orz 
     71         {
     72             node &tmp=E[head][i];
     73             if (tmp.cap>0 && dis[tmp.to]>dis[head]+tmp.cost)
     74             {
     75                 dis[tmp.to]=dis[head]+tmp.cost;
     76                 pre[tmp.to]=head;
     77                 preedge[tmp.to]=i;
     78                 if (!vis[tmp.to])
     79                 {
     80                     vis[tmp.to]=1;
     81                     que.push(tmp.to);
     82                 }
     83             }
     84         }
     85     }
     86     if (dis[T]==INF) return 0;else return 1;
     87 }
     88 
     89 void mcmf()
     90 {
     91     int ans=0;
     92     while (SPFA())
     93     {
     94         int flow=INF;
     95         for (int i=T;pre[i]!=-1;i=pre[i])
     96         {
     97             flow=min(flow,E[pre[i]][preedge[i]].cap);
     98         }
     99         for (int i=T;pre[i]!=-1;i=pre[i])
    100         {
    101             node &tmp=E[pre[i]][preedge[i]];
    102             ans+=flow*tmp.cost;
    103             tmp.cap-=flow;
    104             E[tmp.to][tmp.pos].cap+=flow; 
    105         }
    106     }
    107     cout<<ans<<endl;
    108 }
    109 
    110 int main()
    111 {
    112     init();
    113     mcmf();
    114     return 0;
    115 } 
  • 相关阅读:
    Blank page instead of the SharePoint Central Administration site
    BizTalk 2010 BAM Configure
    Use ODBA with Visio 2007
    Handling SOAP Exceptions in BizTalk Orchestrations
    BizTalk与WebMethods之间的EDI交换
    Append messages in BizTalk
    FTP protocol commands
    Using Dynamic Maps in BizTalk(From CodeProject)
    Synchronous To Asynchronous Flows Without An Orchestration的简单实现
    WSE3 and "Action for ultimate recipient is required but not present in the message."
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5361729.html
Copyright © 2011-2022 走看看