zoukankan      html  css  js  c++  java
  • uva1658 admiral

    费用流。

    裸的拆点最小费用流,一跑就行。

    核弹预警,为何wa20多发。build函数一定要返回true。。。。。。

    太可怕了

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn = 5000 + 10 ;
    const int maxm = 200000 + 10;
    const int inf = 0x3f3f3f3f;
    int g[maxn],v[maxm],nex[maxm],c[maxm],f[maxm],eid;
    int n,m;
    int id[maxn][2],vid,S,T;
    int dist[maxn],pre[maxn];
    bool inque[maxn];
    queue<int> q;
    
    void addedge(int a,int b,int F,int C) {
        v[eid]=b; f[eid]=F; c[eid]=C; nex[eid]=g[a]; g[a]=eid++;
        v[eid]=a; f[eid]=0; c[eid]=-C; nex[eid]=g[b]; g[b]=eid++;    
    }
    
    bool build() {
        memset(id,0,sizeof(id));
        if(!(scanf("%d%d",&n,&m) && n && m)) return false;
        memset(g,-1,sizeof(g)); eid=0; vid=0;
        for(int i=1;i<=n;i++) {
            id[i][0]=++vid;
            id[i][1]=++vid;
            addedge(id[i][0],id[i][1],1,0);
        }
        for(int i=1,u,v,w;i<=m;i++) {
            scanf("%d%d%d",&u,&v,&w);
            if(v!=1 && u!=n) addedge(id[u][1],id[v][0],1,w);
        }
        S=++vid;
        T=++vid;
        addedge(S,id[1][1],2,0);
        addedge(id[n][0],T,2,0);    
        return true;
    }
    
    bool SPFA() {
        memset(dist,0x7f,sizeof(dist));
        memset(inque,0,sizeof(inque));
        memset(pre,0,sizeof(pre));
        dist[S]=0;
        q.push(S);
        inque[S]=1;
        int u;
        while(!q.empty()) {
            u=q.front(); q.pop();
            inque[u]=0;
            for(int i=g[u];~i;i=nex[i])  
                if(f[i] && dist[v[i]]>c[i]+dist[u]) {
                    dist[v[i]]=c[i]+dist[u];
                    pre[v[i]]=i;
                    if(!inque[v[i]]) {
                        q.push(v[i]);
                        inque[v[i]]=1;
                    }
                } 
        }
        return dist[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() {
        int res=0;
        while(SPFA()) 
            res+=augment();    
        printf("%d
    ",res);    
    }
    
    int main() {
        while(build()) solve();
        return 0;
    }
  • 相关阅读:
    HDU 4389 X mod f(x) [数位DP]
    HDU 4370 0 or 1 [01规划最短路]
    HDU 4371 Alice and Bob [简单博弈]
    HDU 4386 Quadrilateral [最大四边形面积]
    HDU 4387 Stone Game [博弈]
    HDU 4385 Moving Bricks [状态压缩DP]
    HDU 4372 Count the Buildings [组合数学]
    几个项目管理网
    计算机信息系统集成资质管理办法
    201005期蘑菇班信息系统项目管理师招生简章
  • 原文地址:https://www.cnblogs.com/invoid/p/5573193.html
Copyright © 2011-2022 走看看