Title Description
There was once a king who had \ (N \) sons.
There are \ (N \) beautiful girls in the Kingdom, and each prince also has his own favorite object.
Each Prince may like more than one object.
Because the princes are old enough to get married, the king wants the princes to marry these \ (N \) girls. Of course, each girl can only marry one prince.
The king asked the wizard to make a statistics for him. He wanted to see what girls his sons liked.
In this way, the wizard made a list of which girls each prince liked, and gave a preliminary matching scheme.
The king looked at the list given to him by the wizard, say: "Your summary is good, but I'm not completely satisfied. I hope you can make a list of women that each prince can marry, which can meet that each Prince's corresponding list is all the girls he likes, and after any Prince chooses a girl from his list as his marriage object, the remaining princes can still choose from their own list The object they like enables all princes to match the girl they like. "
Please help the wizard make a list of what the king is satisfied with.
Input format
The first line contains the integer \ (N \).
The next \ (N \) line contains multiple integers, which describes the list of girls the prince likes. The first integer \ (K \) in each line represents the number of girls the prince likes. The next \ (K \) integers are the number of these \ (K \) girls.
The last line contains \ (N \) integers, indicating the preliminary pairing scheme, and the \ (i \) integer indicates the number of girls paired with the \ (i \) Prince.
Output format
Output a total of \ (N \) lines.
Each line contains multiple integers to describe the list of women that a prince can marry. The first integer \ (L \) represents the number of girls that the prince can marry. The next \ (L \) integers are the numbers of these \ (L \) girls (please arrange them in ascending order).
Data range
\(1 ≤ N ≤ 2000 \), the sum of all \ (K \) shall not exceed \ (200000 \).
Sample input:
4
2 1 2
2 1 2
2 2 3
2 3 4
1 2 3 4
Output example:
2 1 2
2 1 2
1 3
1 4
Problem solution
This problem requires finding all edges. After matching this edge, the bipartite graph can still form a complete matching.
It's easy to think of a strategy: obviously, all the matching edges given must be the answer. Let's enumerate each unmatched edge \ ((a_1,b_1) \), where \ (match[b_1]=a_2 \), \ (match[b_2]=a_1 \). Modify \ (match[b_1]=a_1 \), \ (match[b_2]=0 \), and judge whether \ (a_2 \) can be matched successfully by Hungarian algorithm. If successful, the edge \ ((a_1,b_1) \) is the desired edge.
However, the time complexity of this method is \ (O(NM) \), which will timeout. A faster solution is needed.
Note that the original graph must be a complete match, which means that if \ (a_2 \) can be successfully matched, the last node in the dfs search tree must be \ (b_2 \). And \ (b_2 \) was originally matched with \ (a_1 \). So we found that \ (a_1 → b_1 → a_2 →... → b_2 → a_1 \) constitutes a ring! If there are \ (b_3,b_4,...,b_k \) on the right part of the ring and they have edges with \ (a_1 \), then these B points have the same properties as \ (b_1 \), and \ ((a_1,b_{1...k}) \) is the same answer. These edges no longer need to be judged again by Hungarian algorithm.
It is not difficult to find that all \ (a → B \) in the direction of the ring are unmatched edges, which are women that the prince likes but does not marry\ (B → a \) is the matching edge, which is the marriage scheme on the list listed by the wizard. We establish a directed graph and find the strong connected component in this graph. Then if \ ((a,b) \) satisfies \ (a \), \ (B \) is in the same strong connected component, then this side is the answer.
Time complexity \ (O(N+M) \).
This problem uses the idea of Hungarian algorithm, uses the unique properties of complete matching, and uses Tarjan algorithm to solve the strongly connected component. It is a good problem.
Code
#include<cstdio> #include<vector> #include<algorithm> using namespace std; const int N = 4000 + 5; const int M = 202000 + 5; int n; int head[N], nxt[M], ver[M], tot; int dfn[N], low[N], id, c[N], cnt; int stack[N], top, ins[N]; vector<int> ans; void Add(int x, int y) { nxt[++tot] = head[x]; head[x] = tot; ver[tot] = y; } void Tarjan(int x) { dfn[x] = low[x] = ++id; stack[++top] = x; ins[x] = 1; for (int i = head[x]; i; i = nxt[i]) { int y = ver[i]; if (!dfn[y]) { Tarjan(y); low[x] = min(low[x], low[y]); } else if (ins[y]) low[x] = min(low[x], dfn[y]); } if (dfn[x] == low[x]) { int y; ++cnt; do { y = stack[top--]; ins[y] = 0; c[y] = cnt; } while (x != y); } } int main() { int m, x, y; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &m); while (m--) { scanf("%d", &y); Add(i, n + y); } } for (int i = 1; i <= n; i++) { scanf("%d", &x); Add(n + i, x); } for (int i = 1; i <= n; i++) if (!dfn[i]) { dfn[i] = 1; Tarjan(i); } for (int i = 1; i <= n; i++) { int s = 0; ans.clear(); for (int j = head[i]; j; j = nxt[j]) if (c[i] == c[ver[j]]) { s++; ans.push_back(ver[j]); } printf("%d ", s); sort(ans.begin(), ans.end()); for (int j = 0; j < ans.size(); j++) printf("%d ", ans[j] - n); printf("\n"); } return 0; }