• POJ 3686 The Windy's (费用流)


    【题目链接】 http://poj.org/problem?id=3686

    【题目大意】

      每个工厂对于每种玩具的加工时间都是不同的,
      并且在加工完一种玩具之后才能加工另一种,现在求加工完每种玩具的平均时间

    【题解】

      因为每个工厂加工一个零件在不同的时间是有不同代价的,
      我们发现对于一个工厂在每次加工一个零件时候,时间要加上之前所有的零件的时间的条件
      其实等价于对这个工厂加工的零件乘上1~N的不同系数。
      那么我们将这个工厂对于时间进行拆点,对于费用乘上不同的系数,求一遍费用流即可

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <utility>
    using namespace std;
    const int INF=0x3f3f3f3f;
    typedef pair<int,int> P;
    struct edge{int to,cap,cost,rev;};
    const int MAX_V=10000;
    int V,h[MAX_V],dist[MAX_V],prevv[MAX_V],preve[MAX_V];
    vector<edge> G[MAX_V]; 
    void add_edge(int from,int to,int cap,int cost){
        G[from].push_back((edge){to,cap,cost,G[to].size()});
        G[to].push_back((edge){from,0,-cost,G[from].size()-1});
    }
    int min_cost_flow(int s,int t,int f){
        int res=0;
        fill(h,h+V,0);
        while(f>0){
            priority_queue<P,vector<P>,greater<P> > que;
            fill(dist,dist+V,INF);
            dist[s]=0;
            que.push(P(0,s));
            while(!que.empty()){
                P p=que.top(); que.pop();
                int v=p.second;
                if(dist[v]<p.first)continue;
                for(int i=0;i<G[v].size();i++){
                    edge &e=G[v][i];
                    if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
                        dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
                        prevv[e.to]=v;
                        preve[e.to]=i;
                        que.push(P(dist[e.to],e.to));
                    }
                }
            }
            if(dist[t]==INF)return -1;
            for(int v=0;v<V;v++)h[v]+=dist[v];
            int d=f;
            for(int v=t;v!=s;v=prevv[v]){
                d=min(d,G[prevv[v]][preve[v]].cap);
            }f-=d;
            res+=d*h[t];
            for(int v=t;v!=s;v=prevv[v]){
                edge &e=G[prevv[v]][preve[v]];
                e.cap-=d;
                G[v][e.rev].cap+=d; 
            }
        }return res;
    }
    const int MAX_N=50;
    const int MAX_M=50;
    int T,N,M;
    int z[MAX_N][MAX_M];
    void solve(){
        int s=N+N*M,t=s+1;
        V=t+1;
        for(int i=0;i<=V;i++)G[i].clear();
        for(int i=0;i<N;i++)add_edge(s,i,1,0);
        for(int j=0;j<M;j++){
            for(int k=0;k<N;k++){
                add_edge(N+j*N+k,t,1,0);
                for(int i=0;i<N;i++)add_edge(i,N+j*N+k,1,(k+1)*z[i][j]);
            }
        }printf("%.6f
    ",(double)min_cost_flow(s,t,N)/N);
    }
    void init(){
        scanf("%d%d",&N,&M);
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                scanf("%d",&z[i][j]);
            }
        }
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            init();
            solve();
        }return 0;
    }
  • 相关阅读:
    61组第二次团队作业
    饮水机电路图工作原理及电路图分析
    七种基础模拟电路的用法
    C语言判断一个数是奇数还是偶数
    F28335 UART串口配置及数据发送
    F28335 SPI配置及收发数据
    电容的九大功能
    查询接口---flask+python+mysql
    python参数传递
    java基础
  • 原文地址:https://www.cnblogs.com/forever97/p/poj3686.html
Copyright © 2020-2023  润新知