• POJ 3686 The Windy's


    题意:一个工厂接到了N张订单。他们有M个车间,如果第i张单在第j个车间加工需要花费Zij的时间。现在给出这个Z的矩阵,问做完这N张单需要时间的平均值(总时间/N)包括等待时间。(比如说我在一个车间连续以1个时间单位接了3张单,那么总时间为1+2+3=6,平均值为6/3=2)(N,M<=50)

    给了5000ms。假设第i个单子在第j个车间倒数第k个被加工,那么对应总时间会增加k*Zij。那么接下来的做法就显而易见了,拆下点,将(车间号,倒数第k个加工的席位)作为点来建图,从订单i向这些点连边,边权为k*Zij。KM或者费用流都可以上。ZKWflow跑了1000MS,普通的费用流跑了2000+MS,KM可以跑到0MS。。。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <queue>
      6 #define maxn 2600
      7 #define maxm 1000000
      8 #define INF 1<<30
      9 using namespace std;
     10 
     11 struct ZKW_flow{
     12     int src,sink,e,n;
     13     int first[maxn];
     14     int cap[maxm],cost[maxm],v[maxm],next[maxm];
     15     void init(){
     16         e = 0;
     17         memset(first,-1,sizeof(first));
     18     }
     19 
     20     void add_edge(int a,int b,int cc,int ww){
     21         cap[e] = cc;cost[e] = ww;v[e] = b;
     22         next[e] = first[a];first[a] = e++;
     23         cap[e] = 0;cost[e] = -ww;v[e] = a;
     24         next[e] = first[b];first[b] = e++;
     25     }
     26 
     27     int d[maxn];
     28 
     29     void spfa(){
     30         for(int i = 1;i <= n;i++)   d[i] = INF;
     31         priority_queue<pair<int,int> > q;
     32         d[src] = 0;
     33         q.push(make_pair(0,src));
     34         while(!q.empty()){
     35             int u = q.top().second,dd = -q.top().first;
     36             q.pop();
     37             if(d[u] != dd)   continue;
     38             for(int i = first[u];i != -1;i = next[i]){
     39                 if(cap[i] && d[v[i]] > dd + cost[i]){
     40                     d[v[i]] = dd + cost[i];
     41                     q.push(make_pair(-d[v[i]],v[i]));
     42                 }
     43             }
     44         }
     45         for(int i = 1;i <= n;i++)   d[i] = d[sink] - d[i];
     46     }
     47 
     48     int Mincost,Maxflow;
     49     bool used[maxn];
     50 
     51     int add_flow(int u,int flow){
     52         if(u == sink){
     53             Maxflow += flow;
     54             Mincost += d[src] * flow;
     55             return flow;
     56         }
     57         used[u] = true;
     58         int now = flow;
     59         for(int i = first[u];i != -1;i = next[i]){
     60             int &vv = v[i];
     61             if(cap[i] && !used[vv] && d[u] == d[vv] + cost[i]){
     62                 int tmp = add_flow(vv,min(now,cap[i]));
     63                 cap[i] -= tmp;
     64                 cap[i^1] += tmp;
     65                 now -= tmp;
     66                 if(!now) break;
     67             }
     68         }
     69         return flow - now;
     70     }
     71 
     72     bool modify_label(){
     73         int dd = INF;
     74         for(int u = 1;u <= n;u++)   if(used[u])
     75             for(int i = first[u];i != -1;i = next[i]){
     76                 int &vv = v[i];
     77                 if(cap[i] && !used[vv]) dd = min(dd,d[vv] + cost[i] - d[u]);
     78             }
     79         if(dd == INF)    return false;
     80         for(int i = 1;i <= n;i++)   if(used[i]) d[i] += dd;
     81         return true;
     82     }
     83 
     84     int min_cost_flow(int ss,int tt,int nn){
     85         src = ss,sink = tt,n = nn;
     86         Mincost = Maxflow = 0;
     87         spfa();
     88         while(1){
     89             while(1){
     90                 for(int i = 1;i <= n;i++) used[i] = 0;
     91                 if(!add_flow(src,INF))  break;
     92             }
     93             if(!modify_label()) break;
     94         }
     95         return Mincost;
     96     }
     97 };
     98 
     99 ZKW_flow g;
    100 
    101 int main(){
    102     int kase,n,m,z;
    103     scanf("%d",&kase);
    104     while(kase--){
    105         g.init();
    106         scanf("%d%d",&n,&m);
    107         int S = n+n*m+1,T = n+n*m+2;
    108         for(int i = 1;i <= n;i++)   g.add_edge(S,i,1,0);
    109         for(int i = 1;i <= n*m;i++) g.add_edge(i+n,T,1,0);
    110         for(int i = 1;i <= n;i++){
    111             for(int j = 1;j <= m;j++){
    112                 scanf("%d",&z);
    113                 for(int k = 1;k <= n;k++)   g.add_edge(i,n+(j-1)*n+k,1,k*z);
    114             }
    115         }
    116         int ans = g.min_cost_flow(S,T,T);
    117         printf("%.6f
    ",(ans+0.0)/n);
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    windows server2012 R2 本地策略编辑
    iOS 获取相册中图片的名字 url
    iOS -[PFPASIDataCompressor compressBytes:length:error:shouldFinish:] in PFPGZIPInvocationCompressor.o
    iOS 系统根据导航栏和状态栏自动修改布局
    iOS 本地推送通知
    iOS开发日记59-推荐两本好书
    iOS开发日记57-详解Quartz 2D
    iOS开发日记56-详解UIImage
    iOS开发日记55-隐式与显式动画
    iOS开发日记54-Xcode7调试神技
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3434414.html
Copyright © 2020-2023  润新知