zoukankan      html  css  js  c++  java
  • 洛谷

    https://www.luogu.org/problemnew/show/P4452

    又一道看题解的费用流。

    注意时间也影响节点,像题解那样建边就少很多了。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXN=700005+1;
    const int MAXM=700000;
    const int INF=0x3f3f3f3f;
    struct Edge{
        int to,next,cap,flow,cost;
    }edge[MAXM];
    int head[MAXN],tol;
    int pre[MAXN],dis[MAXN];
    bool vis[MAXN];
    
    int n;
    void init(){
        tol=0;
        memset(head,-1,sizeof(head));
    }
    
    void addedge(int u,int v,int cap,int cost){
        edge[tol].to=v;
        edge[tol].cap=cap;
        edge[tol].cost=cost;
        edge[tol].flow=0;
        edge[tol].next=head[u];
        head[u]=tol++;
    
        edge[tol].to=u;
        edge[tol].cap=0;
        edge[tol].cost=-cost;
        edge[tol].flow=0;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    
    bool spfa(int s,int t){
        queue<int> q;
        memset(dis,INF,sizeof(dis));
        memset(vis,false,sizeof(vis));
        memset(pre,-1,sizeof(pre));
    
        dis[s]=0;
        vis[s]=true;
        q.push(s);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
                    dis[v]=dis[u]+edge[i].cost;
                    pre[v]=i;
                    if(!vis[v]){
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
        }
        if(pre[t]==-1)
            return false;
        else
            return true;
    }
    
    int minCostMaxFlow(int s,int t,int &cost){
        int flow=0;
        cost=0;
        while(spfa(s,t)){
            int Min=INF;
            for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
                if(Min>edge[i].cap-edge[i].flow)
                    Min=edge[i].cap-edge[i].flow;
            }
            for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
                edge[i].flow+=Min;
                edge[i^1].flow-=Min;
                cost+=edge[i].cost*Min;
            }
            flow+=Min;
        }
        return flow;
    }
    /*
    int main(){
        int M,S,T;
        scanf("%d%d%d%d",&N,&M,&S,&T);
        init(N);
        while(M--){
            int u,v,cap,cost;
            scanf("%d%d%d%d",&u,&v,&cap,&cost);
            addedge(u,v,cap,cost);
        }
        int cost=0;
        int flow=minCostMaxFlow(S,T,cost);
    
        printf("%d %d
    ",flow,cost);
    }*/
    
    int getid(int id,int T){
        return T*200+id;
    }
    
    int g[205][205]={};
    int co[205][205]={};
    
    struct Node{
        int a,b,s,t,c;
    }node[2000];
    
    int main() {
        init();
        int s=0,s1=700005,T,m,k;
        scanf("%d%d%d%d",&n,&m,&k,&T);
        int t=getid(0,T);
    
        addedge(s1,s,k,0);//不超过k架飞机
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%d",&g[i][j]);
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%d",&co[i][j]);
            }
        }
    
        for(int i=0;i<n;i++){
            int ti=g[i][0];
            int u=getid(i,T-ti);
            addedge(u,t,k,co[i][0]);
        }
    
        for(int i=0;i<m;i++){
            scanf("%d%d%d%d%d",&node[i].a,&node[i].b,&node[i].s,&node[i].t,&node[i].c);
            int u=getid(node[i].a,node[i].s),v=getid(node[i].b,node[i].t);
            addedge(u,v,1,-node[i].c);
        }
    
        for(int i=0;i<m;i++){
            for(int j=0;j<m;j++){
                if(node[j].t+g[node[j].b][node[i].a]<=node[i].s){
                    int u=getid(node[j].b,node[j].t);int v=getid(node[i].a,node[i].s);
                    addedge(u,v,1,co[node[j].b][node[i].a]);
                }
    
            }
            if(g[0][node[i].a]<=node[i].s){
                int u=0;int v=getid(node[i].a,node[i].s);
                addedge(u,v,1,co[0][node[i].a]);
            }
            if(node[i].t+g[node[i].b][0]<=T){
                int u=getid(node[i].b,node[i].t);int v=t;
                addedge(u,v,1,co[node[i].b][0]);
            }
        }
        /*for(int ti=0;ti<T;ti++){
            for(int u=0;u<n;u++){
                addedge(getid(u,ti),getid(u,ti+1),k,0);
            }
        }*/
    
        /*while(m--){
            int t1,a,t2,b,cost;
            scanf("%d%d%d%d%d",&a,&b,&t1,&t2,&cost);
            int u=getid(a,t1),v=getid(b,t2);
            addedge(u,v,1,-cost);
            for(int i=0;i<n;i++){
                if(i==a)
                    continue;
                int ti=g[i][a];
                if(t1-ti>=0)
                    addedge(getid(i,t1-ti),u,1,co[i][a]);
            }
           // cout<<"cost="<<cost<<endl;
        }*/
    
        int cost;
        int flow=minCostMaxFlow(s1,t,cost);
        printf("%d
    ",-cost);
    }
  • 相关阅读:
    C语言I作业12—学期总结
    # 第一周作业
    C语言Ⅰ博客作业11
    C语言Ⅰ博客作业10
    C语言Ⅰ博客作业09
    C语言Ⅰ博客作业08
    C语言||作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
  • 原文地址:https://www.cnblogs.com/Yinku/p/10619352.html
Copyright © 2011-2022 走看看