Put it simply, put the ID of the cluster I back to I and find the minimum number of steps.
Idea: only deal with the chain shape and the ring, other cases can be ignored, for the chain shape, as long as the inverted line, the ring to find a free put one, then there is the chain.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <stack>using namespace std;const int MAXN = 10005;int culsters[MAXN];int culster_num, file_num;int cnt,num;stack<int> s;void cal() {int next;for (int i = 1; i <= culster_num; i++) {if (culsters[i] == i)continue;else if (culsters[i] != 0) {s.push(i);next = culsters[i];int is_circle = 0;while (1) {if (culsters[next] == i) {is_circle = 1;break;}else if (culsters[next] == 0) {is_circle = 0;break;}s.push(next);next = culsters[next];}int t, j;if (is_circle == 1) {for (j = culster_num; j >= 1; j--) if (culsters[j] == 0)break;printf("%d %d\n", next, j);culsters[j] = culsters[next];while (!s.empty()) {t = s.top();printf("%d %d\n", t, next);culsters[next] = culsters[t];next = t;s.pop();num++;}culsters[next] = culsters[j];culsters[j] = 0;printf("%d %d\n", j, next);}else {while (!s.empty()) {t = s.top();printf("%d %d\n", t, next);culsters[next] = culsters[t];next = t;s.pop();num++;}culsters[next] = 0;}}}if (num == 0) printf("No optimization needed\n");}int main() {int t;scanf("%d", &t);while (t--) {scanf("%d%d", &culster_num, &file_num);memset(culsters, 0, sizeof(culsters));cnt = 1, num = 0;for (int i = 0; i < file_num; i++) {int n, t;scanf("%d", &n);for (int j = 0; j < n; j++) {scanf("%d", &t);culsters[t] = cnt++;}}cal();if (t)printf("\n");}return 0;}