zoukankan      html  css  js  c++  java
  • UVa 11383 少林决胜(二分图最佳完美匹配)

    https://vjudge.net/problem/UVA-11383

    题意:

    给定一个N×N矩阵,每个格子里都有一个正整数W(i,j)。你的任务是给每行确定一个整数row(i),每列也确定一个整数col(i),使得对于任意格子(i,j),w(i,j)<=row(i)+col(j)。所有的row(i)和col(i)只和应尽量小。

    思路:

    利用二分图最佳完美匹配当中的l(x)+l(y)>=w(i,j),直接用KM算法即可。

      1 #include<iostream>
      2 #include<string>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstdio>
      7 using namespace std;
      8 const int maxn=500+5;
      9 
     10 int W[maxn][maxn], n;
     11 int Lx[maxn];
     12 int Ly[maxn];
     13 int Left[maxn];
     14 bool S[maxn], T[maxn];
     15 
     16 bool Match(int i)
     17 {
     18     S[i] = true;
     19     for (int j = 1; j <= n; j++)
     20     {
     21         if (Lx[i] + Ly[j] == W[i][j] && !T[j])
     22         {
     23             T[j] = true;
     24             if (!Left[j] || Match(Left[j]))
     25             {
     26                 Left[j] = i;
     27                 return true;
     28             }
     29         }
     30     }
     31     return false;
     32 }
     33 
     34 void Update()
     35 {
     36     int a = 1 << 30;
     37     for (int i = 1; i <= n; i++)
     38     {
     39         if (S[i])
     40         {
     41             for (int j = 1; j <= n; j++)
     42             {
     43                 if (!T[j])
     44                 {
     45                     a = min(a, Lx[i] + Ly[j] - W[i][j]);
     46                 }
     47             }
     48         }
     49     }
     50     for (int i = 1; i <= n; i++)
     51     {
     52         if (S[i])
     53             Lx[i] -= a;
     54         if (T[i])
     55             Ly[i] += a;
     56     }
     57 }
     58 
     59 void KM()
     60 {
     61     for (int i = 1; i <= n; i++)
     62     {
     63         Left[i] = 0;
     64         Lx[i] = 0;
     65         Ly[i] = 0;
     66         for (int j = 1; j <= n; j++)
     67         {
     68             Lx[i] = max(Lx[i], W[i][j]);
     69         }
     70     }
     71     for (int i = 1; i <= n; i++)
     72     {
     73         while (true)
     74         {
     75             memset(S, 0, sizeof(S));
     76             memset(T, 0, sizeof(T));
     77             if (Match(i))
     78                 break;
     79             else
     80                 Update();
     81         }
     82     }
     83 }
     84 
     85 int main()
     86 {
     87     //freopen("D:\input.txt","r",stdin);
     88     while(~scanf("%d",&n))
     89     {
     90         for(int i=1;i<=n;i++)
     91         {
     92             for(int j=1;j<=n;j++)
     93                 scanf("%d",&W[i][j]);
     94         }
     95         int ans=0;
     96         KM();
     97         for(int i=1;i<=n;i++)
     98         {
     99             printf("%d%c", Lx[i], i == n ? '
    ' : ' ');
    100             ans+=Lx[i];
    101         }
    102         for(int i=1;i<=n;i++)
    103         {
    104              printf("%d%c", Ly[i], i == n ? '
    ' : ' ');
    105             ans+=Ly[i];
    106         }
    107         printf("%d
    ",ans);
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    小胖IT大讲堂之二 Hook实战(一) 魔兽改键工具
    介绍介绍草泥马
    ASP.NET服务端操作ActiveX报错灾难性故障的问题和解决办法
    ASP.NET网络映射驱动器无权限访问的解决方案
    Visual Studio快捷键
    4.2.8 Dating with girls(2)
    4.3.2 Prime Ring Problem
    4.2.3 Knight Moves
    4.2.1 Rescue
    4.2.7 Waiting ten thousand years for Love
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6883944.html
Copyright © 2011-2022 走看看