use crate::internal::OFF;
pub fn maxmatch(
nrows: usize,
ncols: usize,
colstr: &[usize],
rowind: &[usize],
prevcl: &mut [usize],
prevrw: &mut [usize],
marker: &mut [usize],
tryrow: &mut [usize],
nxtchp: &mut [isize],
) -> Result<(/*rowset*/ Vec<usize>, /*colset*/ Vec<usize>), String> {
let mut row: usize;
let mut prow: usize;
let mut pcol: usize;
let mut nextrw: isize;
let mut lastrw: usize;
let mut rowset = vec![0; nrows];
let mut colset = vec![0; ncols];
for nodec in 1..=ncols {
let mut col = nodec;
prevrw[col - OFF] = 0;
prevcl[col - OFF] = 0;
nxtchp[col - OFF] = colstr[col - OFF] as isize;
'l100: loop {
nextrw = nxtchp[col - OFF];
lastrw = colstr[col + 1 - OFF] - 1;
'l400: loop {
if nextrw > 0 {
for xrow in nextrw as usize..=lastrw {
row = rowind[xrow - OFF];
if rowset[row - OFF] == 0 {
break 'l400;
}
}
nxtchp[col - OFF] = -1;
}
tryrow[col - OFF] = colstr[col - OFF];
nextrw = tryrow[col - OFF] as isize;
if lastrw >= nextrw as usize {
for xrow in nextrw as usize..=lastrw {
row = rowind[xrow - OFF];
if marker[row - OFF] < nodec {
tryrow[col - OFF] = xrow + 1;
marker[row - OFF] = nodec;
let nxtcol = rowset[row - OFF];
if nxtcol == col {
return Err("maxmatch: search followed a matching edge".to_string());
} else if nxtcol > 0 {
prevcl[nxtcol - OFF] = col;
prevrw[nxtcol - OFF] = row;
tryrow[nxtcol - OFF] = colstr[nxtcol - OFF];
col = nxtcol;
continue 'l100;
} else {
break 'l400;
}
}
}
}
col = prevcl[col - OFF];
if col > 0 {
continue 'l100;
} else {
break 'l100;
}
}
rowset[row - OFF] = col;
prow = prevrw[col - OFF];
pcol = prevcl[col - OFF];
while pcol > 0 {
if rowset[prow - OFF] != col {
return Err(format!("maxmatch: pointer toward root disagrees with matching. prevcl[{}]={} but colset[{}]={}", col, row, row, rowset[row- OFF]));
}
rowset[prow - OFF] = pcol;
col = pcol;
prow = prevrw[pcol - OFF];
pcol = prevcl[pcol - OFF];
}
break;
}
}
for row in 1..=nrows {
let col = rowset[row - OFF];
if col > 0 {
colset[col - OFF] = row;
}
}
Ok((rowset, colset))
}