The meaning of the question is to give a 01 grid of $N*N$, in which any two rows and any two columns can be exchanged. Ask whether it is possible to form a rectangle with all diagonals equal to 1. and provide an exchange plan.
Just consider swapping any two rows here. There was a problem on Zhihu before that was to determine whether there are $N$ $1$ such that they are in different rows and different columns of the matrix. Question link
If val[i][j]=1, build an edge from i to j. Finally, run bipartite graph matching. Record the final match.
bool flag = true; do{ flag = false; for(int i=1;i<=n;i++) { vis[i] = 0; } for(int i=1;i<=n;i++) { if(right_match[i]==0 && findmatch(i)) { flag = true; } } }while(flag); int k = 0; repp(i,1,n) { k += right_match[i] != 0; } if(k != n) { puts("-1"); return; } repp(i,1,n) { vis[i] = i; } repp(i,1,n) { if(right_match[i]==vis[i])continue; int j = 1; for(;j<=n;j++) { if(vis[j]==right_match[i]) { break; } } cout<< "R "<<vis[j]<<" "<<vis[i]<<endl; int t = vis[j]; vis[j] = vis[i]; vis[i] = t; } }
E Domino Train
The meaning of the question is that $N$ dominoes are given, which is the logarithm of $N$. Then you have to perform N-1 steps of operation, each operation handles the front and back positions of the two dominoes, and ultimately makes the adjacent dominoes have the same number at most.
I have been thinking about this topic for a long time. . . In fact, just run the Euler circuit. . .
For each domino $(A_i,B_i)$, establish an edge from A_i to B_i, and then process each connected block as a unit. For multiple points with odd degrees, connect an edge, and then run the Euler loop from the point with odd degrees as the starting point. . .
Record the final position of each point, use it and find the solution to be processed.
It seems that everything is not difficult starting from the answer, but how to get it done is really difficult. . .
int deg[maxn]; int flag[maxn], ans[maxn], pos[maxn]; vector<int>nums[maxn]; vector<int>path;
voiddfs(int x) { while (edge[x].size()) { int id = edge[x].begin()->first; int to = edge[x].begin()->second; edge[x].erase(id); edge[to].erase(-id); dfs(to); path.push_back(id); } }
voidsolve() { sa(n); repp(i, 1, n) { A.fa[i] = i; } repp(i, 1, n) { int x, y; sa(x), sa(y); edge[x][i] = y; edge[y][-i] = x; deg[x] ++; deg[y] ++; A.fa[A.getfa(x)] = A.getfa(y); } repp(i, 1, n) { nums[A.getfa(i)].push_back(i); } int cnt = 0; int m = n; repp(i, 1, n) { if (nums[i].size() == 0)continue; vector<int>odd; rep(k, 0, nums[i].size()) { if (deg[nums[i][k]] % 2) { odd.push_back(nums[i][k]); } } while (odd.size()>2) { int k1 = odd.back(); odd.pop_back(); int k2 = odd.back(); odd.pop_back(); m++; edge[k1][m] = k2; edge[k2][-m] = k1; } int start = i; if (odd.size())start = odd[0]; dfs(start); while (path.size() != 0) { int id = path.back(); path.pop_back(); if (abs(id) <= n) { if (id<0) { flag[abs(id)] = 1; } ans[++cnt] = abs(id); } } } repp(i, 1, n) { L.fa[i] = i; R.fa[i] = i; pos[ans[i]] = i; } repp(i, 1, n - 1) { int x; sa(x); x = pos[x]; x = L.getfa(x); if (x == 1) { int y = R.getfa(x) + 1; printf("%d %d\n", ans[x], ans[y]); R.fa[R.getfa(x)] = y; L.fa[L.getfa(y)] = x; } else { int y = L.getfa(x - 1); printf("%d %d\n", ans[y], ans[x]); R.fa[R.getfa(y)] = x; L.fa[L.getfa(x)] = y; } } repp(i, 1, n) { if (i>1)printf(" "); printf("%d", flag[i]); } }