Description:
You are given a matrix which is n rows m columns (1 <= n <= m <= 100). You are supposed to choose n elements, there is no more than 1 element in the same row and no more than 1 element in the same column. What is the minimum value of the K_th largest in the n elements you have chosen.
Input:
First line is an integer T (T ≤ 15), the number of test cases. At the beginning of each case is three integers n, m, K, 1 <= K <= n <= m <= 100. Then n lines are given. Each line contains m integers, indicating the matrix. All the elements of the matrix is in the range [1, 10^9].
Output:
For each case, output Case #k: one line first, where k means the case number count from 1. Then output the answer.
Sample Input:
2 2 3 1 1 2 4 2 4 1 3 4 2 1 5 6 6 8 3 4 3 6 8 6 3
Sample Output:
Case #1: 1 Case #2: 3
二分枚举答案,如果a[i][j]<=mid则建一条xi->yj的边,然后对二分图跑最大匹配,如果最大匹配数>=n-k+1,则ans<=mid,否则ans>mid
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queue> 9 #include<set> 10 #include<bitset> 11 #include<map> 12 #include<vector> 13 #include<stdlib.h> 14 #include <stack> 15 using namespace std; 16 #define PI acos(-1.0) 17 #define max(a,b) (a) > (b) ? (a) : (b) 18 #define min(a,b) (a) < (b) ? (a) : (b) 19 #define ll long long 20 #define eps 1e-10 21 #define MOD 1000000007 22 #define N 106 23 #define inf 1e10 24 int n,m,k; 25 int mp[N][N]; 26 int cnt[N][N]; 27 int vis[N]; 28 int link[N]; 29 vector<int> v; 30 31 void build_map(int mid){ 32 memset(cnt,0,sizeof(cnt)); 33 for(int i=0;i<n;i++){ 34 for(int j=0;j<m;j++){ 35 if(mp[i][j]<=mid){ 36 cnt[i][j]=1; 37 } 38 } 39 } 40 } 41 42 bool dfs(int u){ 43 for(int i=0;i<m;i++){ 44 if(!vis[i] && cnt[u][i]){ 45 vis[i]=1; 46 if(link[i]==-1 || dfs(link[i])){ 47 link[i]=u; 48 return true; 49 } 50 } 51 } 52 return false; 53 } 54 bool solve(int mid){ 55 build_map(mid); 56 memset(link,-1,sizeof(link)); 57 int ans=0; 58 for(int i=0;i<n;i++){ 59 memset(vis,0,sizeof(vis)); 60 if(dfs(i)){ 61 ans++; 62 } 63 } 64 65 if(ans>=(n-k+1)) return true; 66 return false; 67 68 69 70 } 71 int main() 72 { 73 int ac=0; 74 int t; 75 scanf("%d",&t); 76 while(t--){ 77 memset(mp,0,sizeof(mp)); 78 scanf("%d%d%d",&n,&m,&k); 79 for(int i=0;i<n;i++){ 80 for(int j=0;j<m;j++){ 81 scanf("%d",&mp[i][j]); 82 } 83 } 84 int low=0; 85 int high=inf; 86 while(low<high){ 87 int mid=(low+high)>>1; 88 if(solve(mid)){ 89 high=mid; 90 //ans=mid; 91 }else{ 92 low=mid+1; 93 } 94 } 95 printf("Case #%d: ",++ac); 96 printf("%d\n",low); 97 98 99 100 } 101 return 0; 102 }
时间: 2024-10-23 06:37:18