zoukankan      html  css  js  c++  java
  • HDU 2853 Assignment(最大完备匹配)

    题目链接

    解题思路

      这题的思路十分巧妙。首先,如果有多条等权值的路径的话,需要优先选择已经选好的那些路径,我们可以把每条边的边权都扩大k倍再加1,这样以来,选好的和没选的等边权的边就能区分开来,而且也不会影响不同边权的边的关系。
      第二个问题就是怎么求改动的次数了,我们把原来的边权扩大k倍,只有选过的边才加1,那么只要最优的选择含有一条原先选过的边,那么结果模k就会多1,用n减去最大边权模k的结果就是改动的次数,注意这个k要比n大,不然取模的时候就取不满0~n了。

    代码

    const int maxn = 1e2+10;
    const int maxm = 30;
    int match[maxn], lx[maxn], ly[maxn], s[maxn];
    int visx[maxn], visy[maxn], pre[maxn];
    int n, m, g[maxn][maxn];
    void find(int k) {
        int y = 0, p = 0; clr(pre, 0); 
        for (int i = 1; i<=m; ++i) s[i] = INF;
        match[y] = k;
        while(1) {
            int x = match[y], d = INF; visy[y] = 1;
            for (int i = 1; i<=m; ++i)
                if (!visy[i]) {
                    if (s[i] > lx[x]+ly[i]-g[x][i]) 
                        s[i] = lx[x]+ly[i]-g[x][i], pre[i] = y;
                    if (d > s[i]) d = s[i], p = i;
                }
            for (int i = 0; i<=m; ++i) {
                if (visy[i]) lx[match[i]] -= d, ly[i] += d;
                else s[i] -= d;
            }
            y = p;
            if (!match[y]) break;
        }
        while(y) match[y] = match[pre[y]], y = pre[y];
    }
    int km() {
        clr(lx, 0x3f); clr(ly, 0); clr(match, 0);
        for (int i = 1; i<=n; ++i)
            clr(visy, 0), find(i);
        int ans = 0;
        for (int i = 1; i<=m; ++i) ans += g[match[i]][i];
        return ans;
    }
    int main() {
        while(~scanf("%d%d", &n, &m)) {
            for (int i = 1; i<=n; ++i)
                for (int j = 1; j<=m; ++j)
                    scanf("%d", &g[i][j]), g[i][j] *= 100;
            int sum = 0;
            for (int i = 1, j; i<=n; ++i)
                scanf("%d", &j), sum += g[i][j], ++g[i][j];
            int res = km();
            printf("%d %d
    ", n-res%100, (res-sum)/100);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS 上线流程
    静态库和动态库的区别
    iOS如何生成.a文件
    苹果公司软件
    iOS 的主要框架
    多线程图解
    判断屏幕横屏/竖屏
    最大堆构建和堆排序
    hadoop2.6.0 + hbase-1.0.0 伪分布配置
    centos6 名字服务dnsmasq配置
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13547378.html
Copyright © 2011-2022 走看看