zoukankan      html  css  js  c++  java
  • 【Luogu】P2053修车(费用流)

      题目链接

      早上状态不好,虚树搞崩只好来刷网络流了qwq。

      (然后我犹豫几秒之后看了题解)

      使用拆点大法把工人拆成n*m个点,然后每个点代表每个时间段的工人,

      然后从车到每个工人点连一条边,权值是耽误的时间,就是这个车在这个时间段用这个工人所用的时间。

      然后跑费用流。

      (然后我太菜了费用流忘了怎么打了,回头一翻自己博客发现居然只是一周之前学的东西)

    #include<cstdio>
    #include<cstdlib>
    #include<cctype>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define maxn 30000
    using namespace std;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    inline int count(int i){    return i&1?i+1:i-1;    }
    
    int dfn[maxn];
    bool vis[maxn];
    int Start,End;
    
    struct Edge{
        int from,next,to,dis,val,flow;
    }edge[maxn*5];
    int head[maxn],num;
    inline void addedge(int from,int to,int dis,int val){
        edge[++num]=(Edge){from,head[from],to,dis,val,0};
        head[from]=num;
    }
    inline void add(int from,int to,int dis,int val){
        addedge(from,to,dis,val);
        addedge(to,from,-dis,0);
    }
    
    struct Ans{
        int dis,val;
        Ans(){dis=val=0;}
    };
    
    int dis[maxn];
    int pre[maxn];
    int flow[maxn];
    
    Ans spfa(){
        Ans ans;
        memset(dis,127/3,sizeof(dis));    int Max=dis[0];
        dis[Start]=0;    flow[Start]=0x7fffffff;
        queue<int>q;    q.push(Start);
        while(!q.empty()){
            int from=q.front();q.pop();vis[from]=0;
            for(int i=head[from];i;i=edge[i].next){
                int to=edge[i].to;
                if(edge[i].dis+dis[from]>=dis[to]||edge[i].val==edge[i].flow)    continue;
                dis[to]=dis[from]+edge[i].dis;
                pre[to]=i;
                flow[to]=min(flow[from],edge[i].val-edge[i].flow);
                if(!vis[to]){
                    vis[to]=1;
                    q.push(to);
                }
            }
        }
        if(dis[End]==Max)    return ans;
        int now=End;    ans.val=flow[End];    ans.dis=dis[End];
        while(now!=Start){
            int ret=pre[now];
            edge[ret].flow+=flow[End];
            edge[count(ret)].flow-=flow[End];
            now=edge[ret].from;
        }
        return ans;
    }
    
    double ans;
    
    int main(){
        int m=read(),n=read();End=maxn-2;
        for(int i=1;i<=n;++i)
            add(Start,i,0,1);
        for(int j=1;j<=m;++j)
            for(int i=1;i<=n;++i)    add((i-1)*m+n+j,End,0,1);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j){
                int x=read();
                for(int k=1;k<=n;++k)
                    add(i,(k-1)*m+j+n,k*x,1);
            }
        while(1){
            Ans now=spfa();
            if(!now.val)    break;
            ans+=now.dis*now.val;
        }
        printf("%.2lf",ans/n);
        return 0;
    }
  • 相关阅读:
    两个半成品的ORM
    Mayberry小镇的管理 | 三种截然不同的领导风格 3M
    敏捷的目的(方向)错了以后……
    Error:java: Compilation failed: internal java compiler error
    java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)
    看mybatis日志模块时涉及的动态代理
    看的顺眼的却Destination Unreachable
    如何下载钉钉回放视频
    不想学习时看一看会有帮助的,“但行好事,莫问前程”
    守护线程
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8250220.html
Copyright © 2011-2022 走看看