Is setting high mismatch and gap penalties sufficient to distinguish perfectly mapping reads?
The short answer: No, setting extremely high penalties (100 or 1000) does not seem to work. I'm not sure why.

The medium answer: Since I posted the question, I did a bit of exploring, and it looks like the reads that perfectly match are the reads that are not soft clipped and that have an edit distance of zero, as indicated by the CIGAR string and NM tag, respectively.

The long answer: See https://standage.github.io/how-to-distinguish-perfectly-mapped-reads-from-a-sambam-file.html.