UVA11383 Golden Tiger Claw

UVA11383 Golden Tiger Claw_第1张图片

 

 UVA11383 Golden Tiger Claw_第2张图片

 

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

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

代码:

 

 1 #include
 2 #include
 3 #include
 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("\n");
65         for(int i=1;i<=n;++i){
66             printf("%d ",q_shu[i]);
67             ans+=q_shu[i];
68         }
69         printf("\n%d\n",ans);
70     }
71     return 0;
72 }
View Code

 

你可能感兴趣的:(UVA11383 Golden Tiger Claw)