zoukankan      html  css  js  c++  java
  • bzoj2245: [SDOI2011]工作安排

    费用流。

    这道题的模型比较明显,拆点也是很容易看出来的。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 1000 + 10;
    const int maxm = 500000 + 10;
    const int inf = 0x3f3f3f3f;
    int g[maxn],v[maxm],f[maxm],c[maxm],next[maxm],eid;
    int idn[maxn],idm[maxn];
    int a[maxn][5];
    int n,m,S,T,vid,u;
    int d[maxn],pre[maxn];
    int q[maxn],l,r;
    bool inque[maxn];
    
    void addedge(int a,int b,int F,int C) {
        v[eid]=b; f[eid]=F; c[eid]=C; next[eid]=g[a]; g[a]=eid++;
        v[eid]=a; f[eid]=0; c[eid]=-C; next[eid]=g[b]; g[b]=eid++;    
    }
    
    void build() {
        memset(g,-1,sizeof(g));
        scanf("%d%d",&n,&m);
        S=1; T=2;
        vid=2;
        for(int i=1,t;i<=m;i++) {
            idm[i]=++vid;
            scanf("%d",&t);
            addedge(S,idm[i],t,0);
        }
        for(int i=1;i<=n;i++) {
            idn[i]=++vid;    
            for(int j=1,t;j<=m;j++) {
                scanf("%d",&t);
                if(t==1) addedge(idm[j],idn[i],inf,0);
            }
        }
        for(int i=1,t;i<=n;i++) {
            scanf("%d",&t);
            for(int j=1;j<=t;j++) scanf("%d",&a[j][1]);
            a[t+1][1]=inf;
            for(int j=1;j<=t+1;j++) scanf("%d",&a[j][2]);
            for(int j=1;j<=t+1;j++)
                addedge(idn[i],T,a[j][1]-a[j-1][1],a[j][2]);
        }    
    }
    
    bool SPFA() {
        memset(d,0xe3f,sizeof(d));
        d[S]=0; l=r=0;
        inque[q[r++]=S]=1;
        while(l<r) {
            inque[u=q[l++]]=0;
            for(int i=g[u];~i;i=next[i]) if(f[i] && d[v[i]]>d[u]+c[i]) {
                d[v[i]]=d[u]+c[i];
                pre[v[i]]=i;
                if(!inque[v[i]]) {
                    inque[q[r++]=v[i]]=1;    
                }
            }
        }
        return d[T]<inf;
    }
    
    int augment() {
        int aug=inf,res=0;
        for(int i=T;i!=S;i=v[pre[i]^1]) {
            aug=min(aug,f[pre[i]]);
        }
        for(int i=T;i!=S;i=v[pre[i]^1]) {
            f[pre[i]]-=aug;
            f[pre[i]^1]+=aug;
            res+=c[pre[i]]*aug;
        }
        return res;    
    }
    
    void solve() {
        long long res=0;
        while(SPFA()) res+=augment();
        printf("%lld
    ",res);
    }
    
    int main() {
        build();
        solve();
        return 0;    
    }
  • 相关阅读:
    LINQ查询操作符之First、FirstOrDefault、Last、LastOrDefault、ElementAt、ElementAtOrDefault、Contains、Any、All、Coun
    .Net 使用的快捷键
    P2073 送花
    洛谷P1514 引水入城
    花园
    八数码难题
    并查集题目整理
    树链剖分(强势借鉴)
    模拟题
    考试整理
  • 原文地址:https://www.cnblogs.com/invoid/p/5611072.html
Copyright © 2011-2022 走看看