Given a matrix n rows m column select n number to ensure that the N number is not the same row of peers, calculate the number of K the smallest, two-part answer, and then we for each a[i][j]<=mid we set an edge and then two to the maximum match must be greater than or equal to n-k-1 (because it is the K large Not the K-pit for a long time to find out)
#include <algorithm>#include<stdio.h>#include<string.h>#include<vector>#include<iostream>using namespacestd;Const intmaxn= -+5;structBPM {intN, M;//number of left and right verticesvector<int> G[MAXN];//adjacency Table intLEFT[MAXN];//Left[i] is the number of the match point on the right point I, 1 indicates that there is no BOOLT[MAXN];//T[i] to the right of the first I point is marked intRIGHT[MAXN];//for minimum coverage BOOLS[MAXN];//for minimum coverage voidInitintN) { This->n =N; for(inti =0; I < n; i++) g[i].clear (); } voidAddedge (intUintv) {g[u].push_back (v); } BOOLMatchintu) {S[u]=true; for(inti =0; I < g[u].size (); i++) { intv =G[u][i]; if(!T[v]) {T[v]=true; if(Left[v] = =-1||match (Left[v])) {Left[v]=u; return true; } } } return false; } //find the maximum match intsolve () {memset (left,-1,sizeof(left)); intAns =0; for(intU =0; U < n; u++) {//from the left node U start augmentationmemset (S),0,sizeof(S)); memset (T,0,sizeof(T)); if(Match (U)) ans++; } returnans; }}s;intA[MAXN][MAXN];voidAddintNintMintmid) {s.init (n); for(intI=0; i<n; i++) for(intj=0; j<m; J + +) if(a[i][j]<=mid) S.addedge (I,J);}intMain () {intn,m,k; intCAs; scanf ("%d",&CAs); for(intCc=1; cc<=cas; Cc++) {scanf ("%d%d%d",&n,&m,&k); intL=0, r=0; for(intI=0; i<n; i++) for(intj=0; j<m; J + +) {scanf ("%d",&A[i][j]); R=Max (r,a[i][j]); } intans=0; while(l<=R) {intMid= (l+r) >>1; Add (N,m,mid); intnum=S.solve (); if(num>=n-k+1) {ans=mid; r=mid-1; }Else{L=mid+1; }} printf ("Case #%d:%d\n", Cc,ans); } return 0;}
View Code
Two points + binary matching