zoukankan      html  css  js  c++  java
  • uva1349Optimal Bus Route Design

    二分图最小权完美匹配。

    一个最小费用流就能跑了,记住检查一下,容量是否跑满,如果没有跑满,就说明没有完美匹配。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 500+10;
    const int maxm = 50000 + 10;
    const int inf = 0x3f3f3f3f;
    
    int g[maxn],v[maxm],f[maxm],c[maxm],nex[maxm],eid;
    int id[maxn][2],vid;
    int n,ans,S,T;
    bool inque[maxn];
    int q[maxm],dist[maxn],pre[maxn];
    
    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() {
        if(scanf("%d",&n)==1&&n) {
            memset(g,-1,sizeof(g)); eid=0; vid=0;
            S=++vid; T=++vid;
            for(int i=1;i<=n;i++) {
                id[i][0]=++vid;
                id[i][1]=++vid;
                addedge(S,id[i][0],1,0);
                addedge(id[i][1],T,1,0);
            }
            
            for(int i=1,j,d;i<=n;i++)  
                while(scanf("%d",&j) && j) {
                    scanf("%d",&d);
                    addedge(id[i][0],id[j][1],1,d);
                }
            return true;
        }
        return false;
    }
    
    bool SPFA() {
        int u,l,r;
        l=r=0;
        memset(dist,0x3f,sizeof(dist));
        dist[S]=0;
        inque[q[r++]=S]=1;
        while(l<r) {
            inque[u=q[l++]]=0;
            for(int i=g[u];~i;i=nex[i]) 
                if(f[i] && dist[v[i]]>dist[u]+c[i]) {
                dist[v[i]]=dist[u]+c[i];
                pre[v[i]]=i;
                if(!inque[v[i]]) inque[q[r++]=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+=aug*c[pre[i]];
        }
        ans+=aug;
        return res;
    }
    
    void solve() {
        ans=0;
        int res=0;
        while(SPFA()) res+=augment();
        if(ans!=n) printf("N
    ");
        else printf("%d
    ",res);    
    }
    
    int main() {
        while(build()) solve();
        return 0;
    }
  • 相关阅读:
    MVC模式的学生信息增删改查
    常用排序算法
    2803 爱丽丝·玛格特罗依德
    3118 高精度练习之除法
    中秋练习题
    poj2011
    P1558 色板游戏
    P1830 轰炸III
    P1656 炸铁路
    1067 机器翻译
  • 原文地址:https://www.cnblogs.com/invoid/p/5574176.html
Copyright © 2011-2022 走看看