zoukankan      html  css  js  c++  java
  • UVA11383 二分图最佳匹配的性质的应用

     1 /*UVA11383
     2 二分图最佳匹配的性质的应用
     3 首先看这道题的题面:
     4 给定一个N*N的矩阵,每个格子上填上权值W[i][j];
     5 现在要求找到row[1]..row[n],和col[1]...col[n]。分别对应每一行和每一列。
     6 使得对于任意格子(i,j),W[i][j]<=row[i]+col[j]
     7 还要求出row[i]和col[i]总和的最小值
     8 而最优匹配(二分后的权值和最大)后,顶标数组会满足Lx(x)+Ly(y)>=W[x][y]这个条件,而sigm(Lx(i)+Ly(j))是最小的。
     9 */
    10 #include <cmath>
    11 #include <algorithm>
    12 #include <stdlib.h>
    13 #include <iostream>
    14 #include <string.h>
    15 #include <stdio.h>
    16 #include <stack>
    17 #include <set>
    18 #include <map>
    19 #include <vector>
    20 #define typed int
    21 #define INF 1<<30
    22 #define maxn 550
    23 #define eps 1e-6
    24 using namespace std;
    25 int n;
    26 typed W[maxn][maxn];
    27 typed Lx[maxn],Ly[maxn];//顶标
    28 int lef[maxn];//由A到B的映射
    29 bool S[maxn],T[maxn];
    30 
    31 bool match(int i){
    32     S[i]=true;
    33     for(int j=1;j<=n;j++) if (fabs(Lx[i]+Ly[j]-W[i][j])<eps && !T[j]){
    34         T[j]=true;
    35         if (!lef[j] || match(lef[j])){
    36             lef[j]=i;
    37             return true;
    38         }
    39     }
    40     return false;
    41 }
    42 
    43 void update(){
    44     typed a=INF;
    45     for(int i=1;i<=n;i++) if(S[i]){
    46         for(int j=1;j<=n;j++) if(!T[j])
    47             a=min(a,Lx[i]+Ly[j]-W[i][j]);
    48     }
    49     for(int i=1;i<=n;i++){
    50         if (S[i]) Lx[i]-=a;
    51         if (T[i]) Ly[i]+=a;
    52     }
    53 }
    54 void KM(){
    55     for(int i=1;i<=n;i++){
    56         lef[i]=Lx[i]=Ly[i]=0;
    57         for(int j=1;j<=n;j++){
    58             Lx[i]=max(Lx[i],W[i][j]);
    59         }
    60     }
    61     for(int i=1;i<=n;i++){
    62         for(;;){
    63             for(int j=1;j<=n;j++) S[j]=T[j]=false;
    64             if (match(i)) break;else update();
    65         }
    66     }
    67 }
    68 int nextint(){
    69     int x;
    70     scanf("%d",&x);
    71     return x;
    72 }
    73 void read(){
    74     for(int i=1;i<=n;i++)
    75     for(int j=1;j<=n;j++)
    76     W[i][j]=nextint();
    77 }
    78 void printans(){
    79     for(int i=1;i<=n;i++)
    80     if (i<n) printf("%d ",Lx[i]);else printf("%d
    ",Lx[i]);
    81     for(int i=1;i<=n;i++)
    82     if (i<n) printf("%d ",Ly[i]);else printf("%d
    ",Ly[i]);
    83     int sum=0;
    84     for(int i=1;i<=n;i++) sum+=Lx[i]+Ly[i];
    85     printf("%d
    ",sum);
    86 }
    87 int main(){
    88     while(cin>>n){
    89         read();
    90         KM();
    91         printans();
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    STL函数对象和Lambda表达式
    STL算法之排序算法
    STL 算法
    STL源码剖析---根据最新版本的g++4.9.0(支持C++11)的修订(1)空间配置器
    STL Iterator的里里外外(一)?
    STL对比解说——关联容器
    Select单进程非阻塞TCP echo服务器
    TCP建立(3次握手)与终止(4次挥手)
    TIME_WAIT状态
    C标准I/O库
  • 原文地址:https://www.cnblogs.com/little-w/p/3644090.html
Copyright © 2011-2022 走看看