• UVA11383 Golden Tiger Claw


     

    题意:给你一个n*n的矩阵,让你给矩阵的每一行每一列附一个值,使得每一个矩阵中的点的行和列的值的和大于等于该点的权值,并使得行列值之和最小。

    思路:其实这道题我们就是跑一遍KM算法就行了,因为在KM过程中我们始终有两点之间的期望值之和大于等于两点之间的距离,我们就可以把期望值当做行列的值就行了,最终总和就是匹配完的图的所有行列的大小总和。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=505;
     6 const int Inf=0x3f3f3f3f;
     7 int val[N][N],q_heng[N],q_shu[N],vis_heng[N],vis_shu[N];
     8 int match[N],slack[N],n;
     9 bool dfs(int heng){
    10     vis_heng[heng]=1;
    11     for(int shu=1;shu<=n;++shu){
    12         if(vis_shu[shu]) continue;
    13         int gap=q_heng[heng]+q_shu[shu]-val[heng][shu];
    14         if(gap==0){
    15             vis_shu[shu]=true;
    16             if(match[shu]==-1||dfs(match[shu])){
    17                 match[shu]=heng;
    18                 return true;
    19             }
    20         }
    21         else{
    22                 slack[shu]=min(slack[shu],gap);
    23         }
    24     }
    25     return false;
    26 }
    27 void KM(){
    28     memset(match,-1,sizeof(match));
    29     memset(q_shu,0,sizeof(q_shu));
    30     for(int i=1;i<=n;++i){
    31         q_heng[i]=val[i][1];
    32         for(int j=2;j<=n;++j){
    33             q_heng[i]=max(q_heng[i],val[i][j]);
    34         }
    35     }
    36     for(int i=1;i<=n;++i){
    37         memset(slack,0x3f,sizeof(slack));
    38         while(true){
    39             memset(vis_heng,0,sizeof(vis_heng));
    40             memset(vis_shu,0,sizeof(vis_shu));
    41             if(dfs(i)) break;
    42             int d=Inf;
    43             for(int j=1;j<=n;++j)
    44                 if(!vis_shu[j]) d=min(d,slack[j]);
    45             for(int j=1;j<=n;++j){
    46                 if(vis_heng[j]) q_heng[j]-=d;
    47                 if(vis_shu[j]) q_shu[j]+=d;
    48                 else slack[j]-=d;
    49             }
    50         }
    51     }
    52 }
    53 int main(){
    54     while(scanf("%d",&n)==1){
    55         for(int i=1;i<=n;++i)
    56         for(int j=1;j<=n;++j)
    57             scanf("%d",&val[i][j]);
    58         KM();
    59         int ans=0;
    60         for(int i=1;i<=n;++i){
    61             printf("%d ",q_heng[i]);
    62             ans+=q_heng[i];
    63         }
    64         printf("
    ");
    65         for(int i=1;i<=n;++i){
    66             printf("%d ",q_shu[i]);
    67             ans+=q_shu[i];
    68         }
    69         printf("
    %d
    ",ans);
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    linux tomcat 突然验证码出不来
    使用open live writer客户端写博客
    创建自己的maven模板
    Dynamic Web Module 3.0 requires Java 1.6 or newer
    win10 操作配置备忘
    Maven使用
    ORA-12514: TNS:listener does not currently know of service …
    PlantUML——4.实例演示1
    C语言基础(一)
    Linux系统挂载FAT32的U盘
  • 原文地址:https://www.cnblogs.com/li-jia-hao/p/12870538.html
Copyright © 2020-2023  润新知