• UVA11383 Golden Tiger Claw —— KM算法


    题目链接:https://vjudge.net/problem/UVA-11383

    题解:

    根据KM()算法,标杆满足:l(x) + l(y) >= w(x, y)

    当求完最大权匹配之后,所有标杆在满足:l(x) + l(y) >= w(x, y) 的条件下,和最小。

    代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int INF = 2e9;
     5 const LL LNF = 9e18;
     6 const int mod = 1e9+7;
     7 const int MAXN = 500+10;
     8 
     9 int nx, ny;
    10 int g[MAXN][MAXN], linker[MAXN], lx[MAXN], ly[MAXN], slack[MAXN];
    11 bool visx[MAXN], visy[MAXN];
    12 
    13 bool DFS(int x)
    14 {
    15     visx[x] = true;
    16     for(int y = 1; y<=ny; y++)
    17     {
    18         if(visy[y]) continue;
    19         int tmp = lx[x] + ly[y] - g[x][y];
    20         if(tmp==0)
    21         {
    22             visy[y] = true;
    23             if(linker[y]==-1 || DFS(linker[y]))
    24             {
    25                 linker[y] = x;
    26                 return true;
    27             }
    28         }
    29         else
    30             slack[y] = min(slack[y], tmp);
    31     }
    32     return false;
    33 }
    34 
    35 void KM()
    36 {
    37     memset(linker, -1, sizeof(linker));
    38     memset(ly, 0, sizeof(ly));
    39     for(int i = 1; i<=nx; i++)
    40     {
    41         lx[i] = -INF;
    42         for(int j = 1; j<=ny; j++)
    43             lx[i] = max(lx[i], g[i][j]);
    44     }
    45 
    46     for(int x = 1; x<=nx; x++)
    47     {
    48         for(int i = 1; i<=ny; i++)
    49             slack[i] = INF;
    50         while(true)
    51         {
    52             memset(visx, 0, sizeof(visx));
    53             memset(visy, 0, sizeof(visy));
    54 
    55             if(DFS(x)) break;
    56             int d = INF;
    57             for(int i = 1; i<=ny; i++)
    58                 if(!visy[i])
    59                     d = min(d, slack[i]);
    60 
    61             for(int i = 1; i<=nx; i++)
    62                 if(visx[i])
    63                     lx[i] -= d;
    64             for(int i = 1; i<=ny; i++)
    65             {
    66                 if(visy[i]) ly[i] += d;
    67                 else slack[i] -= d;
    68             }
    69         }
    70     }
    71 }
    72 
    73 int main()
    74 {
    75     int n;
    76     while(scanf("%d",&n)!=EOF)
    77     {
    78         nx = ny = n;
    79         for(int i = 1; i<=nx; i++)
    80         for(int j = 1; j<=ny; j++)
    81             scanf("%d",&g[i][j]);
    82 
    83         KM();
    84         int sum = 0;
    85         for(int i = 1; i<=nx; i++) printf("%d ", lx[i]), sum += lx[i];
    86         printf("
    ");
    87         for(int i = 1; i<=ny; i++) printf("%d ", ly[i]), sum += ly[i];
    88         printf("
    ");
    89         printf("%d
    ", sum);
    90     }
    91 }
    View Code
  • 相关阅读:
    集合
    第五天
    第四天
    第二天
    ieee 期刊缩写(转载)
    JAVA学习笔记03
    JAVA学习笔记2
    JAVA学习笔记01
    Latex 图片排版
    非奇异终端滑模
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7832084.html
Copyright © 2020-2023  润新知