| #include <bits/stdc++.h> |
| using namespace std; |
|
|
| vector<vector<int>> create_map(int N, int M, vector<int> A, vector<int> B) { |
| |
| if (N == 1) { |
| return vector<vector<int>>(1, vector<int>(1, 1)); |
| } |
|
|
| |
| struct Edge { int u, v; }; |
| vector<Edge> edges(M); |
| for (int i = 0; i < M; ++i) { |
| edges[i] = {A[i], B[i]}; |
| } |
| vector<vector<pair<int,int>>> adj(N+1); |
| for (int i = 0; i < M; ++i) { |
| int u = edges[i].u, v = edges[i].v; |
| adj[u].push_back({v, i}); |
| adj[v].push_back({u, i}); |
| } |
|
|
| |
| |
| |
|
|
| |
| vector<char> used(M, 0); |
| vector<vector<int>> trails; |
| |
| auto hasUnusedEdgeAt = [&](int v)->bool{ |
| for (auto &p : adj[v]) if (!used[p.second]) return true; |
| return false; |
| }; |
|
|
| |
| vector<int> verticesWithDeg; |
| for (int v = 1; v <= N; ++v) { |
| if (!adj[v].empty()) verticesWithDeg.push_back(v); |
| } |
| if (verticesWithDeg.empty()) { |
| |
| |
| |
| int K = max(1, min(240, N)); |
| vector<vector<int>> C(K, vector<int>(K, 1)); |
| return C; |
| } |
|
|
| |
| while (true) { |
| int start = -1; |
| for (int v = 1; v <= N; ++v) { |
| if (hasUnusedEdgeAt(v)) { start = v; break; } |
| } |
| if (start == -1) break; |
| vector<int> path; |
| int cur = start; |
| path.push_back(cur); |
| while (true) { |
| int picked = -1; |
| int nxt = -1; |
| for (auto &p : adj[cur]) { |
| int nb = p.first, eid = p.second; |
| if (!used[eid]) { picked = eid; nxt = nb; break; } |
| } |
| if (picked == -1) break; |
| used[picked] = 1; |
| cur = nxt; |
| path.push_back(cur); |
| } |
| trails.push_back(path); |
| } |
|
|
| |
| vector<vector<int>> simpleAdj(N+1); |
| for (int i = 0; i < M; ++i) { |
| int u = edges[i].u, v = edges[i].v; |
| simpleAdj[u].push_back(v); |
| simpleAdj[v].push_back(u); |
| } |
|
|
| auto bfs_path = [&](int s, int t)->vector<int> { |
| vector<int> prev(N+1, -1); |
| queue<int>q; |
| q.push(s); |
| prev[s] = s; |
| while (!q.empty()) { |
| int x = q.front(); q.pop(); |
| if (x == t) break; |
| for (int y : simpleAdj[x]) { |
| if (prev[y] == -1) { |
| prev[y] = x; |
| q.push(y); |
| } |
| } |
| } |
| vector<int> path; |
| if (prev[t] == -1) { |
| |
| |
| path.push_back(s); |
| return path; |
| } |
| int cur = t; |
| while (cur != s) { |
| path.push_back(cur); |
| cur = prev[cur]; |
| } |
| path.push_back(s); |
| reverse(path.begin(), path.end()); |
| return path; |
| }; |
|
|
| |
| vector<int> W; |
| if (!trails.empty()) { |
| W = trails[0]; |
| for (size_t i = 1; i < trails.size(); ++i) { |
| int endW = W.back(); |
| int startT = trails[i].front(); |
| vector<int> bridge = bfs_path(endW, startT); |
| |
| for (size_t k = 1; k < bridge.size(); ++k) W.push_back(bridge[k]); |
| |
| for (size_t k = 1; k < trails[i].size(); ++k) W.push_back(trails[i][k]); |
| } |
| } |
|
|
| |
| vector<char> seenV(N+1, 0); |
| for (int x : W) if (x>=1 && x<=N) seenV[x] = 1; |
| int lastV = W.empty() ? verticesWithDeg[0] : W.back(); |
| for (int v = 1; v <= N; ++v) { |
| if (!adj[v].empty() && !seenV[v]) { |
| vector<int> bridge = bfs_path(lastV, v); |
| for (size_t k = 1; k < bridge.size(); ++k) W.push_back(bridge[k]); |
| lastV = v; |
| seenV[v] = 1; |
| } |
| } |
|
|
| |
| if (W.empty()) { |
| int K = min(240, max(1, N)); |
| vector<vector<int>> C(K, vector<int>(K, 1)); |
| return C; |
| } |
|
|
| |
| |
| int maxK = 240; |
| int L = (int)W.size(); |
| int K = min(maxK, max(N, (L + 1) / 2)); |
| int needLen = 2 * K - 1; |
| if ((int)W.size() < needLen) { |
| |
| int padVal = W.back(); |
| while ((int)W.size() < needLen) W.push_back(padVal); |
| } else if ((int)W.size() > needLen) { |
| |
| W.resize(needLen); |
| } |
|
|
| |
| vector<vector<int>> C(K, vector<int>(K, 1)); |
| for (int i = 0; i < K; ++i) { |
| for (int j = 0; j < K; ++j) { |
| int idx = i + j; |
| if (idx >= 0 && idx < (int)W.size()) C[i][j] = W[idx]; |
| else C[i][j] = W.back(); |
| } |
| } |
| return C; |
| } |
|
|
| int main() { |
| ios::sync_with_stdio(false); |
| cin.tie(nullptr); |
| int T; |
| if (!(cin >> T)) return 0; |
| while (T--) { |
| int N, M; |
| cin >> N >> M; |
| vector<int> A(M), B(M); |
| for (int i = 0; i < M; ++i) cin >> A[i] >> B[i]; |
| auto C = create_map(N, M, A, B); |
| int P = (int)C.size(); |
| cout << P << "\n"; |
| for (int i = 0; i < P; ++i) { |
| cout << (int)C[i].size() << (i+1==P?'\n':' '); |
| } |
| cout << "\n"; |
| for (int i = 0; i < P; ++i) { |
| for (int j = 0; j < (int)C[i].size(); ++j) { |
| if (j) cout << ' '; |
| cout << C[i][j]; |
| } |
| cout << "\n"; |
| } |
| } |
| return 0; |
| } |