UVA 11383 Golden Tiger Claw

Golden Tiger Claw

Time Limit: 8000ms

Memory Limit: 131072KB

This problem will be judged on UVA. Original ID: 11383
64-bit integer IO format: %lld      Java class name: Main

Omi, Raymondo, Clay and Kimiko are on new adventure- in search of new Shen Gong Wu. But Evil Boy Genius Jack Spicer is also there. Omi and Jack found the Shen Gong Wu at the same time so they rushed for it but alas they touched it at the same time. Then what? It is time for Xiaolin Showdown.

Jack challenged Omi to play a game. The game is simple! There will be an N*N board where each cell in the board contains some number. They have to assign numbers to each row and column separately so that $w(i,j) \leq row(i) + col(j) $where is the number assigned to the cell located at ith row and jth column, row(i) is the number assigned to ith row and col(j) is the number assigned to jth column. That is simple isnt it? Well the main part is that you have to minimize $\sum_{1\leq i \leq n}(row(i) + col(i))$.

Jack has taken his favorite Monkey Stuff and Omi has taken Golden Tiger Claw. With the help of this Golden Tiger Claw, he can go anywhere in the world. He has come to you and seeking your help. Jack is using his computer to solve this problem. So do it quick! Find the most optimal solution for Omi so that you can also be part of history in saving the world from the darkness of evil.

INPUT

Input contains 15 test cases. Each case starts with N. Then there are N lines containing N numbers each. All the numbers in input is positive integer within the limit 100 except N which can be at most 500.

OUTPUT

For each case in the first line there will be N numbers, the row assignments. In the next line there will N column assignment. And at the last line the minimum sum should be given. If there are several possible solutions give any.

SAMPLE INPUT

2

1 1

1 1

OUTPUT FOR SAMPLE INPUT

1 1

0 0

2

解题:来自大白书上的题目,KM算法的一个副产品,$L(x) + L(y) \geq w(x,y)$ KM算法结束后,所有顶标之和是最小的.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 510;
 4 const int INF = 0x3f3f3f3f;
 5 int W[maxn][maxn],Lx[maxn],Ly[maxn],slack[maxn];
 6 int n,Link[maxn];
 7 bool S[maxn],T[maxn];
 8 bool match(int u){
 9     S[u] = true;
10     for(int v = 0; v < n; ++v){
11         if(T[v]) continue;
12         int d = Lx[u] + Ly[v] - W[u][v];
13         if(!d){
14             T[v] = true;
15             if(Link[v] == -1 || match(Link[v])){
16                 Link[v] = u;
17                 return true;
18             }
19         }else if(slack[v] > d) slack[v] = d;
20     }
21     return false;
22 }
23 void update(){
24     int d = INF;
25     for(int v = 0; v < n; ++v)
26         if(!T[v] && slack[v] < d)
27             d = slack[v];
28     for(int u = 0; u < n; ++u){
29         if(S[u]) Lx[u] -= d;
30         if(T[u]) Ly[u] += d;
31         else slack[u] -= d;
32     }
33 }
34 int KM(){
35     for(int u = 0; u < n; ++u){
36         Lx[u] = -INF;
37         Ly[u] = 0;
38         Link[u] = -1;
39         for(int v = 0; v < n; ++v)
40             Lx[u] = max(Lx[u],W[u][v]);
41     }
42     for(int u = 0; u < n; ++u){
43         for(int v = 0; v < n; ++v)
44             slack[v] = INF;
45         while(true){
46             memset(S,false,sizeof S);
47             memset(T,false,sizeof T);
48             if(match(u)) break;
49             update();
50         }
51     }
52     int ret = 0;
53     for(int v = 0; v < n; ++v)
54         if(Link[v] > -1) ret += W[Link[v]][v];
55     return ret;
56 }
57 int main(){
58     while(~scanf("%d",&n)){
59         memset(W,0,sizeof W);
60         for(int i = 0; i < n; ++i)
61             for(int j = 0; j < n; ++j)
62                 scanf("%d",W[i] + j);
63         int ret = KM();
64         for(int i = 0; i < n; ++i)
65             printf("%d%c",Lx[i],i + 1 == n?‘\n‘:‘ ‘);
66         for(int i = 0; i < n; ++i)
67             printf("%d%c",Ly[i],i + 1 == n?‘\n‘:‘ ‘);
68         printf("%d\n",ret);
69     }
70     return 0;
71 }

时间: 2024-10-01 18:00:49

UVA 11383 Golden Tiger Claw的相关文章

uva 11383 Golden Tiger Claw (KM算法)

uva 11383 Golden Tiger Claw 题目大意:给定一个N×N的矩阵,每个格子里都有一个正整数w(i,j).你的任务是给每行确定一个整数row(i), 每列也确定一个整数col(i),使得对于格子(i,j),w(i,j)<=row(i)+col(j).所有row(i)和col(j)的总和最小. 解题思路:KM算法. #include <cstdio> #include <cstring> #include <algorithm> #include

UVA 11383 - Golden Tiger Claw(二分图完美匹配扩展)

UVA 11383 - Golden Tiger Claw 题目链接 题意:给定每列和每行的和,给定一个矩阵,要求每个格子(x, y)的值小于row(i) + col(j),求一种方案,并且所有行列之和的和最小 思路:A二分图完美匹配的扩展,行列建二分图,权值为矩阵相应位置的值,做一次KM算法后,所有顶标之和就是最小的 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algor

UVA 11383 Golden Tiger Claw 金虎爪(KM算法)

题意:给一个n*n的矩阵,每个格子中有正整数w[i][j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i]+col[j]恒成立.先输row,再输出col,再输出全部总和(总和应尽量小). 思路: KM算法中的顶标就是保持了Lx[i]+ly[j]>=g[i][j]再求最大权和匹配的,但这个最大权和并没有关系.我们可以将row[i]看成一个男的,col[i]看成一个女的,这样男女的总数就相等.一般来说,Lx[i]或Ly[i]仅需要取该行/列中最

UVA11383 Golden Tiger Claw

题目 UVA11383 Golden Tiger Claw 做法 \(KM\)好题啊,满足所有边\(l(x)+l(y)≥w(x,y)\)(个人理解,如不对请及时留言),这样能满足\(\sum\limits_i^n(l(x)+l(y))\)最小值 My complete code #include<bits/stdc++.h> using namespace std; typedef long long LL; const LL maxn=1e3,inf=0x3f3f3f3f; LL n,mi;

训练指南 UVA - 11383(KM算法的应用 lx+ly &gt;=w(x,y))

layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" catalog: true mathjax: true tags: - KM算法 - 训练指南 Golden Tiger Claw UVA - 11383 题意 给一个n*n的矩阵,每个格子中有正整数w[i[j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i

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 #inclu

(KM) uva 11383

题意: 给定n*n的矩阵,每个格子有个值s[i][j],现在要求对每行和每列各分配一个值,r[i],c[i]使得对所有的格子都有s[i][j]<=r[i]+c[j]成立,并且sum{r[i]}+sum{c[i]}尽量小. 直接KM啊..SB题啊... #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #includ

UVA 11383 KM性质

点击打开链接 题意:一个n*n的矩阵每个格子里有一个正整数w(i,j)你的任务是确定每行一个整数row(i)每列一个整数col(i),对每个格子都有w(i,j)<=row(i)+col(j)所有row(i)和col(i)和尽量小. 思路:本题利用KM算法l(x)+l(y)>=w(x,y)的性质直接可以知道得出的顶标之和即为最小的. #include <stdio.h> #include <string.h> #include <iostream> #incl

UVA - 11396 Claw Decomposition(二分图染色)

题目大意:给你一张无向图,每个点的度数都是3.你的任务是判断能否把它分解成若干个爪(每条边只能属于一个爪) 解题思路:二分图染色裸题.可以得出:爪的中心点和旁边的三个点的颜色是不一样的 #include <cstdio> #include <cstring> using namespace std; #define N 310 #define M 2010 struct Edge{ int to, Next; }E[M]; int head[N], color[N], tot; i