The time limit for this question in poj is 15000 Ms. Looking at all DT, it is at least scary ......
The question is, N boys and N girls tell you the numbers of girls that each boy prefers, and then give an initial match (this initial match is a complete match ), then find all possible complete matches and output them in ascending order. Of course, if it is violent (of course I have never tried it), 2000 boys and 2000 girls, up to 20 million targeted edges, will be quite disappointing ......
I read a report from zanniu and turned it into a strongly connected problem:
First, create a Graph Based on the given directed edge, and then add a reverse edge to the graph based on the final complete match (that is, link the girl to the boys' edge based on the complete match). In this graph, A strongly connected point must be a valid point. Sort them and output them.
I started to use the priority queue and thought it would be very fast. I ran 3800 + MS and changed it to sort, which is 3400 MS +. The following code is used:
# Include <cstdio> # include <cstring> # include <stack> # include <queue> # include <algorithm> using namespace STD; const int n = 4010; struct node {int val; bool operator <(const node & A) const {return. val <Val ;}}; struct edge {int S, E, next;} edge [300010]; int N, e_num, vis_num, CNT; int head [N], tim [N], low [N], instack [N], belong [N]; void addedge (int A, int B) {edge [e_num]. S = A; edge [e_num]. E = B; edge [e_num]. next = head [a]; head [] = E_num ++;} void getmap () {int I, j, M, X; e_num = 0; memset (Head,-1, sizeof (head )); for (I = 1; I <= N; I ++) {scanf ("% d", & M); For (j = 1; j <= m; j ++) {scanf ("% d", & X); addedge (I, n + x) ;}}for (I = 1; I <= N; I ++) {scanf ("% d", & X); addedge (n + X, I) ;}} stack <int> st; void Tarjan (INT X) {int I, j; Tim [x] = low [x] = ++ vis_num; ST. push (x); instack [x] = 1; for (I = head [X]; I! =-1; I = edge [I]. next) {int u = edge [I]. e; If (Tim [u] =-1) {Tarjan (U); If (low [u] <low [x]) low [x] = low [u];} else if (instack [u] & Tim [u] <low [x]) low [x] = Tim [u];} If (Tim [x] = low [x]) {CNT ++; do {J = ST. top (); ST. pop (); instack [J] = 0; belong [J] = CNT;} while (J! = X);}/* sort by sort, it will be faster void out (int A [], int Len) {sort (a + 1, A + 1 + Len ); printf ("% d", Len); For (Int J = 1; j <Len; ++ J) printf ("% d", a [J]); printf ("% d \ n", a [Len]);} */void solve () {int I, j, A [n]; CNT = vis_num = 0; memset (TIM,-1, sizeof (Tim); memset (low, 0, sizeof (low); memset (instack, 0, sizeof (instack )); for (I = 1; I <= 2 * n; I ++) {If (Tim [I] =-1) Tarjan (I) ;} node cur; priority_queue <node> q; for (I = 1; I <= N; I ++) {int num = 0; For (j = H EAD [I]; J! =-1; j = edge [J]. next) {int u = edge [J]. e; If (belong [u] = belong [I]) {cur. val = u-n; q. push (cur); num ++ ;}} printf ("% d", num); While (! Q. empty () {node v = Q. top (); q. pop (); printf ("% d", V. val);} puts ("");}/* use sort code for (I = 1; I <= N; I ++) {// traverse the edges in the graph, if the start point and end point are in the same connected component, the valid point is int num = 0; For (j = head [I]; J! =-1; j = edge [J]. next) {int u = edge [J]. e; If (belong [I] = belong [u]) {A [++ num] = u-n ;}} out (a, num );} * // puts (""); note that the zoj output requires an empty line more than the poj output.} int main () {While (~ Scanf ("% d", & N) {getmap (); solve ();} return 0 ;}