zoukankan      html  css  js  c++  java
  • Golden Tiger Claw UVA

    这题使我对km多了一些看法

    写给自己看。。

    km结束后bx[i] + by[j] == w[i][j], 所以所有bx与by的和即为w的和

    而且记住bx[i] + by[j] >= w[i][j] 这个式子 那么bx与by的最小值 即为km结束后的值

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #define mem(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int maxn = 550, INF = 0x7fffffff;
    int usedx[maxn], usedy[maxn], w[maxn][maxn], bx[maxn], by[maxn], cx[maxn], cy[maxn];
    int nx, ny, n, minn, min_value;
    
    bool dfs(int u)
    {
        usedx[u] = 1;
        for(int i=1; i<=ny; i++)
        {
            if(usedy[i] == -1)
            {
                int t = bx[u] + by[i] - w[u][i];
                if(t == 0)
                {
                    usedy[i] = 1;
                    if(cy[i] == -1 || dfs(cy[i]))
                    {
                        cy[i] = u;
                        cx[u] = i;
                        return 1;
                    }
                }
                else if(t > 0)
                    minn = min(minn, t);
            }
        }
        return 0;
    }
    
    int km()
    {
        mem(cx, -1);
        mem(cy, -1);
        mem(bx, -1);
        mem(by, 0);
        for(int i=1; i<=nx; i++)
            for(int j=1; j<=ny; j++)
                bx[i] = max(bx[i], w[i][j]);
        for(int i=1; i<=nx; i++)
        {
            while(1)
            {
                minn = INF;
                mem(usedx, -1);
                mem(usedy, -1);
                if(dfs(i)) break;
                for(int j=1; j<=nx; j++)
                    if(usedx[j] != -1) bx[j] -= minn;
                for(int j=1; j<=ny; j++)
                    if(usedy[j] != -1) by[j] += minn;
            }
        }
        min_value = 0;
        for(int i=1; i<=n; i++)
            if(cx[i] != -1)
                min_value += w[i][cx[i]];
    
        return min_value;
    
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    scanf("%d",&w[i][j]);
            nx = ny = n;
            int ans = km();
        for(int i=1; i<=nx; i++)
        {
            if(i != 1) printf(" ");
            printf("%d", bx[i]);
        }
        printf("
    ");
        for(int i=1; i<=ny; i++)
        {
            if(i != 1) printf(" ");
            printf("%d", by[i]);
        }
        printf("
    ");
        cout<< ans <<endl;
    
        }
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    select选中值传递到后台action中
    select into from 与insert into select from区别
    存储过程
    layer
    下拉框两级联动
    无限纠结——Zedboard上跑ubuntu详解
    静态时序分析SAT
    设计模式-(构型模式)
    内存断点调试的原理
    C语言中使用静态函数的好处
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9427996.html
Copyright © 2011-2022 走看看