NC14363. Graph Generator
描述
DreamGrid has made a graph generator. The generator will take in a single integer n and generate an undirected graph with n vertices.
More specifically, the generator will generate an empty graph G and a permutation p of {1, 2, ..., n} . After that, the generator will do the following operations n times and during the q-th operation:
Given the final generated graph, DreamGrid would like to know all the pq and Sq.
输入描述
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers n and m (1 ≤ n ≤ 105, 0 ≤ m ≤ min(105, ) -- the number of vertices and the number of edges.
Each of the next m lines contains two integers ui and vi (1 ≤ ui, vi ≤ n). There will be no self loops or multiple edges.
It is guaranteed that neither the sum of all n nor the sum of all m exceeds 2 *106.
输出描述
For each test case, if the the graph cannot be generated by the generator, output "No" in the first line. Otherwise, output "Yes" in the first line. Then in the i-th of the following line, output two integers pi and si (1 ≤ pi ≤ n) followed with si integers: a1, a2, ..., asi (1 ≤ aj ≤ n) -- the index of the newly created vertex and the subset during the i-th operation. If there are multiple solutions, print any of them.
示例1
输入:
3 3 0 4 4 1 2 2 3 3 4 2 4 5 5 1 2 2 3 3 4 4 5 2 4
输出:
Yes 1 0 2 0 3 0 Yes 1 0 4 0 3 1 4 2 2 1 3 No
C++11(clang++ 3.9) 解法, 执行用时: 423ms, 内存消耗: 16504K, 提交时间: 2019-01-08 11:55:29
#include <cstdio> #include <vector> const int N = 1e5 + 10; std::vector<int> tree[N]; std::vector<int> adj[N]; int deg[N], ind[N], anc[N], size[N]; bool dfs(int u) { size[u] = 1; for (auto &&v: tree[u]) { anc[v] = anc[u] + 1; if (!dfs(v)) return false; size[u] += size[v]; } return deg[u] == anc[u] + size[u] - 1; } void generate(int u) { for (auto &&v: tree[u]) { generate(v); } printf("%d %d", u + 1, (int)tree[u].size()); for (auto &&v: tree[u]) { printf(" %d", v + 1); } puts(""); } int main() { int T; scanf("%d", &T); for (int cas = 1; cas <= T; ++cas) { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) { deg[i] = ind[i] = anc[i] = 0; tree[i].clear(); adj[i].clear(); } std::vector<std::pair<int, int>> edges(m); for (int i = 0; i < m; ++i) { int u, v; scanf("%d%d", &u, &v); --u, --v; edges[i] = {u, v}; adj[u].push_back(v); adj[v].push_back(u); deg[u]++, deg[v]++; } for (auto &&e: edges) { int u = e.first, v = e.second; if (deg[u] > deg[v] || (deg[u] == deg[v] && u < v)) ++ind[v]; else ++ind[u]; } for (int v = 0; v < n; ++v) { if (!ind[v]) continue; int u = -1; for (auto &&i: adj[v]) if (deg[i] > deg[v] || (deg[i] == deg[v] && i < v)) { if (u == -1 || ind[u] < ind[i]) u = i; } tree[u].push_back(v); } bool valid = true; for (int i = 0; i < n && valid; ++i) { if (!ind[i]) valid &= dfs(i); } if (!valid) puts("No"); else { puts("Yes"); for (int i = 0; i < n; ++i) { if (!ind[i]) generate(i); } } } return 0; }