#include #define endl '\n' #define TRACE(x) cerr << #x << " = " << x << endl //#define ONPC using namespace std; template inline bool chkmax(T &x, const T1 &y) { return x < y ? x = y, true : false; } template inline bool chkmin(T &x, const T1 &y) { return x > y ? x = y, true : false; } const int MAXN = 401; struct Log { vector> log; Log() { this->log.clear(); } Log& operator +=(const Log &other) { for (const auto &log : other.log) this->log.push_back(log); return *this; } void push(pair p) { /* pair rc = p; swap(rc.first, rc.second); bool found = false; for (const auto &log : this->log) { if (log == p || log == rc) { found = true; break; } } */ this->log.push_back(p); } void pop() { this->log.pop_back(); } int size() const { return this->log.size(); } }; struct HeapElement { int idx; int swapCost; Log ans; HeapElement() { } HeapElement(int idx, int swapCost, Log ans) { this->idx = idx; this->swapCost = swapCost; this->ans = ans; } bool operator <(const HeapElement &other) const { return this->swapCost > other.swapCost; } }; ///common functions ostream& operator <<(ostream &os, const Log &one) { os << one.log.size() << endl; for (const auto &log : one.log) os << log.first << ' ' << log.second << endl; return os; } Log& min(Log &a, Log &b) { if (a.size() < b.size()) return a; return b; } HeapElement& min(HeapElement &a, HeapElement &b) { if (a.swapCost < b.swapCost) return a; return b; } int n; int perm[MAXN]; int typePos; int costPos[MAXN][MAXN]; int typeVal; int costVal[MAXN][MAXN]; void read() { cin >> n; for (int i = 1; i <= n; i++) cin >> perm[i]; cin >> typePos; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cin >> costPos[i][j]; } cin >> typeVal; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cin >> costVal[i][j]; } } Log ans, tmp; long long minCost = LLONG_MAX; void solve(long long currCost) { long long minCost = LLONG_MAX; for (int i = 1; i <= n; i++) { if (perm[i] != i) { long long cost = costPos[i][perm[i]] + costVal[perm[i]][perm[perm[i]]]; chkmin(minCost, cost); } } if (minCost == LLONG_MAX) { if (chkmin(::minCost, currCost)) ans = tmp; return; } for (int i = 1; i <= n; i++) { if (perm[i] != i) { long long cost = costPos[i][perm[i]] + costVal[perm[i]][perm[perm[i]]]; if (cost == minCost) { tmp.push({i, perm[i]}); swap(perm[i], perm[perm[i]]); solve(currCost + minCost); tmp.pop(); swap(perm[i], perm[perm[i]]); } } } } void solve() { solve(0ll); cout << ans; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); #ifndef ONPC freopen("sorting.in", "rt", stdin); freopen("sorting.out", "wt", stdout); #endif // ONPC read(); solve(); return EXIT_SUCCESS; }