zoukankan      html  css  js  c++  java
  • bzoj:1834: [ZJOI2010]network 网络扩容

    Description

    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。

    Input

    输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。

    Output

    输出文件一行包含两个整数,分别表示问题1和问题2的答案。

    Sample Input

    5 8 2
    1 2 5 8
    2 5 9 9
    5 1 6 2
    5 1 1 8
    1 2 8 7
    2 5 4 9
    1 2 1 1
    1 4 2 1

    Sample Output

    13 19
     
     
     
    费用流直接套模板就行了……
    没想到手写煞笔spfa居然能跑这么快,再优化下空间可以进前十喔……
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    struct na{
        int x,y,z,f,ne;
    };
    int n,m,l[1002],r[1002],num=0,p,ch,ans=0,
    g[1002],d[1002],c[1002],k,co[21001],x[21001],y[21001],z[21001],dis[1002],ro[1002],qi[1002],an=0,mi[1002];
    na b[21001];
    bool bo[1002];
    const int INF=1e9;
    queue<int> q;
    inline int min(int x,int y){return x>y?y:x;}
    inline void spfa(){
        q.push(n+1);
        bo[n+1]=1;
        for (register int i=0;i<=n+1;i++) dis[i]=INF;
        mi[n+1]=INF;dis[n+1]=0;
        while(!q.empty()){
            int k=q.front();q.pop();bo[k]=0;
            if (k==n) continue;
            for (int i=l[k];i;i=b[i].ne){
                if (b[i].z>0&&dis[b[i].y]>b[i].f+dis[k]){
                    dis[b[i].y]=b[i].f+dis[k];
                    mi[b[i].y]=min(mi[k],b[i].z);
                    ro[b[i].y]=i;
                    qi[b[i].y]=k;
                    if (!bo[b[i].y]){
                        bo[b[i].y]=1;
                        q.push(b[i].y);
                    }
                }
            }
        }
    }
    inline int read(){
        p=0;ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') p=p*10+ch-48, ch=getchar();
        return p;
    }
    inline int add(int x,int y,int z,int f){
        num++;
        if (l[x]==0) l[x]=num;else b[r[x]].ne=num;
        b[num].x=x;b[num].y=y;b[num].z=z;b[num].f=f;r[x]=num;
    }
    inline void in(int x,int y,int z,int f){
        add(x,y,z,f);add(y,x,0,-f);
    }
    inline int sap(int x,int f){
        if (x==n) return f;
        int h=0,q;
        for (register int i=d[x];i;i=b[i].ne)
        if (b[i].z&&g[x]==g[b[i].y]+1){
            q=sap(b[i].y,min(b[i].z,f-h));
            h+=q;
            b[i].z-=q;b[((i-1)^1)+1].z+=q;d[x]=i;
            if (h==f) return h;
        }
        if (g[1]==n) return h;
        c[g[x]]--;
        if (!c[g[x]]) g[1]=n;
        g[x]++;c[g[x]]++;d[x]=l[x];
        return h;
    }
    int main(){
        register int i;
        n=read();m=read();k=read();
        for (i=1;i<=m;i++){
            x[i]=read();y[i]=read();z[i]=read();co[i]=read();
            in(x[i],y[i],z[i],0);
        }
        for (;g[1]<n;ans+=sap(1,INF));
        for (i=1;i<=m;i++) in(x[i],y[i],INF,co[i]);
        in(n+1,1,k,0);
        for(;;){
            spfa();
            if (dis[n]==INF) break;
            an+=mi[n]*dis[n];
            for (i=n;i;i=qi[i]) b[ro[i]].z-=mi[n],b[((ro[i]-1)^1)+1].z+=mi[n];
        }
        printf("%d %d",ans,an);
    }
  • 相关阅读:
    分解质因数算法
    js 的 Math 对象
    字符串操作
    简化求质数算法
    数值类型小数点后是否可以接零问题
    新博第一篇,思考的重要性与求质数算法
    一、制作屏幕录像
    四、同步线程
    常见问题
    jni数据处理
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5186985.html
Copyright © 2011-2022 走看看