1. 程式人生 > 其它 >CF 1500 C

CF 1500 C

CF 1500 C
題意:

​ 給你兩個 \(n \times m\) 的矩陣 A,B(1 \(\leq\) n,m \(\leq\) 1500),矩陣的元素均為 [1,n] 內的整數。

​ 每一次操作你可以選定一列作為每一行的關鍵字,按照關鍵字從小到大的順序把所有行排序得到一個新矩陣。這裡使用的排序是穩定的,即如果有兩行的關鍵字相同,則按照在原矩陣的先後順序排序。

你可以進行不超過 5000 次操作,問你能否將 A 變成 B。不能變成輸出 −1,否則輸出一種可行的操作序列。


題解:

​ 首先考慮由於排序是穩定的,那麼我們一定可以確定 A 中的每一行最後對應著 B 的哪一行,(當然對應不起來就 -1 了)

​ 現在考慮處理出來一個數組 p[i] 表示 B 的第 i 行是 A 的第 p[i] 行,那麼可以發現,我們最後要讓 p[i] 到第 i 個位置上,設 pos[i] 為 A的第 i 行所在位置,即要求 \(\forall\) pos[p[i]]<pos[p[i+1]] 。

​ 那麼考慮對於每一列的操作,如果在該列 k 中 A(p[i],k) < A(p[i+1],k),那麼無事發生,如果存在 A(p[i],k) > A(p[i+1],k) ,那麼如果操作該列,一定需要在後面有一個使得 p[i],p[i+1] 再交換回來的操作,即有一個操作 j 中 A(p[i],j) < A(p[i+1],j)

​ 那麼一個圖論模型 自然 出現了,如果一個操作 x 中所有的 A(p[i],x) <= A(p[i+1],x),那麼貪心的我們肯定用這個操作,因為不會變劣,即 x 向 每個 A(p[i],x) < A(p[i+1],x) 的 i 連邊,代表 x 操作後 i 就被 “解放” 了,而如果存在 A(p[i],x) > A (p[i+1],x) ,那麼要求就是這些 i 在之後的操作中會被反過來,即 i 向 x 連邊,代表所有的這種 i 被解放後 x 才能被釋放掉。跑一遍拓撲排序,倒序輸出方案。