• Uva1349Optimal Bus Route Design(二分图最佳完美匹配)(最小值)


    题意:

    给定n个点的有向图问,问能不能找到若干个环,让所有点都在环中,且让权值最小,KM算法求最佳完美匹配,只不过是最小值,所以把边权变成负值,输出时将ans取负即可

    这道题是在VJ上交的

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 100 + 5;
    const int inf = 0x3f3f3f3f;
    bool visr[maxn], visl[maxn];
    int n, delta, w[maxn][maxn], lx[maxn], ly[maxn], lft[maxn];
    inline bool match( int x ){
        visl[x] = 1;
        for( int y=1; y<=n; y++ )
            if( lx[x]+ly[y]==w[x][y] && !visr[y] ){
                visr[y] = 1;
                if( !lft[y] || match(lft[y]) ){
                    lft[y] = x;
                    return 1;
                }
            }
        return 0;
    }
    
    inline void update(){
        for( int i=1; i<=n; i++ ) if( visl[i] )
            for( int j=1; j<=n; j++ ) if( !visr[j] )
                delta = min( delta, lx[i]+ly[j]-w[i][j] );
        for( int i=1; i<=n; i++ ){
            if( visl[i] ) lx[i] -= delta;
            if( visr[i] ) ly[i] += delta;
        }
    }
    
    inline int KM(){
        for( int i=1; i<=n; i++ ){
            lft[i] = ly[i] = 0;
            lx[i] = -inf;
            for( int j=1; j<=n; j++ )
                lx[i] = max(lx[i], w[i][j]);
        }
        for( int i=1; i<=n; i++ ){
            while(1){
                delta = inf;
                memset( visr, 0, sizeof(visr) );
                memset( visl, 0, sizeof(visl) );
                if( match(i) ) break;
                update();
            }
        }
        int res = 0;
        for( int i=1; i<=n; i++ ) res += w[lft[i]][i];
        return res;
    }
    
    int main(){
        // freopen("in.txt", "r", stdin);
        while( ~scanf("%d", &n) && n ){
            for( int i=1; i<=n; i++ ) 
                for( int j=1; j<=n; j++ ) w[i][j] = -inf;        //不能使用memset( w, -inf, sizeof(w) );
            for( int i=1; i<=n; i++ ){
                int j;
                while( ~scanf("%d", &j) && j ){
                    int d;
                    scanf("%d", &d);
                    w[i][j] = max( -d, w[i][j] );
                }
            }
            int ans = KM();
            if( -ans>=inf ) puts("N");        
            else printf("%d
    ", -ans);
        }
    
        return 0;
    }
  • 相关阅读:
    【BIGEMAP一键离线地图服务】
    android 应用签名的作用
    UniPush使用指南
    Android平台云端打包证书使用说明
    Android平台签名证书(.keystore)生成指南
    时序数据库技术体系-时序数据存储模型设计(原理)
    时序数据库技术体系 – 初识InfluxDB(原理)
    Influxdb原理详解
    jquery.easing 和 jquery.transit 动画插件的使用
    vue 移动端日期选择组件 vue-mobile-calendar
  • 原文地址:https://www.cnblogs.com/WAautomaton/p/10901435.html
Copyright © 2020-2023  润新知