• 【网络流】Modular Production Line


    【网络流】Modular Production Line

    焦作上的一道,网络流24题中的原题....

    • https://nanti.jisuanke.com/t/31715
      给出了1e5个点,但是因为最多200条边,也就是最多用到400个点,所用先离散化,然后建图。
      建图:
      1.对权值为w的区间[u,v],加边id(u)->id(v+1),容量为1,费用为-w;
      2.对所有相邻的点加边id(i)->id(i+1),容量为正无穷,费用为0;
      3.建立源点汇点,由源点s向最左侧的点加边,容量为K,费用为0,由最右侧的点向汇点加边,容量为K,费用为0
      4.跑出最大流后,最小费用取绝对值就是能获得的最大权

    离散化那里不太熟
    spfa的slf优化能快200ms

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=10010;
    const int maxm=100010;
    const int inf=0x3f3f3f3f;
    struct edge{
        int to,next,cap,flow,cost;
    }e[maxm];
    int head[maxn],tol,cost;
    int pre[maxn],dis[maxn];
    bool vis[maxn];
    int N;
    void init(int n){
        N=n;tol=1;cost=0;
        memset(head,0,sizeof(head));
    }
    void addedge(int u,int v,int cap,int cost){
        ++tol;
        e[tol].to=v;e[tol].next=head[u];e[tol].cap=cap;e[tol].cost=cost;e[tol].flow=0;
        head[u]=tol;
        ++tol;
        e[tol].to=u;e[tol].next=head[v];e[tol].cap=0;e[tol].flow=0;e[tol].cost=-cost;
        head[v]=tol;
    }
    bool spfa(int s,int t){
        deque<int>q;
        for (int i = 0; i <=N ; ++i) {
            dis[i]=inf;
            vis[i]=false;
            pre[i]=-1;
        }
        dis[s]=0;
        vis[s]=true;
        q.push_front(s);
        while (!q.empty()){
            int u=q.front();
            q.pop_front();
            vis[u]=0;
            for(int i=head[u];i;i=e[i].next){
                int v=e[i].to;
                if(e[i].cap>e[i].flow&&dis[v]>dis[u]+e[i].cost){
                    dis[v]=dis[u]+e[i].cost;
                    pre[v]=i;
                    if(!vis[v]){
                        vis[v]=true;
                        if(!q.empty()){
                            if(dis[v]<dis[q.front()]) q.push_front(v);
                            else q.push_back(v);
                        }
                        else q.push_back(v);
                    }
                }
            }
        }
        if(pre[t]==-1) return false;
        else return true;
    }
    int mcfc(int s,int t){
        int flow=0;
        while (spfa(s,t)){
            int minn=inf;
            for(int i=pre[t];i!=-1;i=pre[e[i^1].to]){
                if(minn>e[i].cap-e[i].flow){
                    minn=e[i].cap-e[i].flow;
                }
            }
            for(int i=pre[t];i!=-1;i=pre[e[i^1].to]){
                e[i].flow+=minn;
                e[i^1].flow-=minn;
                cost+=e[i].cost*minn;
            }
            flow+=minn;
        }
        return flow;
    }
    struct node{
        int a,b,c;
    }f[300];
    map<int,int>mp;
    int main(){
       int T;scanf("%d",&T);
       int n,m,k,cnt;int a,b,w;
       while (T--){
           scanf("%d%d%d",&n,&m,&k);
           cnt=0;mp.clear();
           for (int i = 1; i <= k; ++i) {
               scanf("%d%d%d",&a,&b,&w);
               f[i]=node{a,b+1,w};
               mp[a]=mp[b+1]=1;
           }
           map<int,int>::iterator it;
           for(it=mp.begin();it!=mp.end();it++){
               int id=it->first;
               mp[id]=++cnt;
           }
           init(cnt+5);
           int s=0,t=cnt+1;
           addedge(0,1,m,0);
           addedge(cnt,t,m,0);
           for (int i = 1; i <cnt ; ++i) {
               addedge(i,i+1,inf,0);
           }
           for (int j = 1; j <=k ; ++j) {
               addedge(mp[f[j].a],mp[f[j].b],1,-f[j].c);
           }
           mcfc(s,t);
           printf("%d
    ",-cost);
       }
    }
    
    
    不要忘记努力,不要辜负自己 欢迎指正 QQ:1468580561
  • 相关阅读:
    【转】突破区块链不可能三角:异步共识组 [Monoxide]
    [转]王嘉平:Monoxide 原理详解,如何用极简架构突破不可能三角
    【转】区块链公链的 3 大性能难点、5 大体验障碍
    使用ShowDoc在线管理API接口文档
    云和恩墨大讲堂电子刊2019年4月刊发布
    墙裂推荐 | 漫画解读Elasticsearch原理,看完你就懂
    DBASK数据库提问平台问题集萃,首批近二十位专家团曝光
    WIN10安装GPU版tensorflow
    cobbler的网页操作
    cobbler的网页操作
  • 原文地址:https://www.cnblogs.com/smallocean/p/9685916.html
Copyright © 2020-2023  润新知