zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    C# webBrowser模拟登陆填充操作等(写网页注册机之类的时候要用到)
    【FLASH教程】Adobe Flash CS4 官方中下载及安装
    [转载]下载rtmpe协议的视频文件
    SQLite操作的帮助类
    Windows及.NET Framework版本检测工具
    纪念一个曾经的软件产品(六)——快捷方式,联系人,任务管理器
    ASP.net Web API综合示例
    Task及其异常处理的若干事项
    Macbook换硬盘导系统
    【转】 矩阵分解方法及 在推荐系统中的应用
  • 原文地址:https://www.cnblogs.com/forever97/p/poj3686.html
Copyright © 2011-2022 走看看