Title Link: BZOJ-1098
Problem analysis
Only when there are edges between the two points can they be in different buildings, that is, if there is no edge between the two points they must be in the same building.
Then the request is to find the original map of the connected block.
However, the number of sides of the original map is n^2 level, very large, we can not directly find the complement map.
You can use a linked list to optimize the BFS approach, starting with all points added to a list.
Each time we find a connected block BFS, take a point in the list, delete it in the list, join the queue, and then each time we remove the first element x, enumerate each edge of X, delete the end of the edge y from the list and add it to a temporary linked list.
After all the edges of X are enumerated, the remaining points in the original list are no edges with X, and the points in the complement map have edges with X, and these points are added to the queue.
Then use the temporary list to replace the original list, the original list is the remaining points.
This allows the BFS to find all the connected blocks several times.
Each point is only deleted from the list 1 times, each edge is traversed only once, the total time complexity is O (n + m).
Code
#include <iostream> #include <cstdlib> #include <cstring> #include <cmath> #include <cstdio > #include <algorithm> #include <queue>using namespace std;const int maxn = 100000 + 5, MAXM = 2000000 + 5;in line void Read (int &num) {char c, c = GetChar (); while (C < ' 0 ' | | c > ' 9 ') c = GetChar (); Num = C-' 0 '; c = GetChar (); while (c >= ' 0 ' && C <= ' 9 ') {num = num * + C-' 0 '; c = GetChar ();}} int n, m, Top, R1, R2, Sum;int ANS[MAXN], LAST[MAXN], next[maxn];bool inlist[maxn];struct Edge{int v; Edge *next;} E[MAXM * 2], *p = E, *point[maxn];inline void Addedge (int x, int y) {++p; P-v = y; P-Next = point[x]; POINT[X] = P;} queue<int> q;inline void Add (int x, int y) {Next[y] = next[x];if (next[x]) last[next[x]] = y; Next[x] = y; Last[y] = x;} inline void Delete (int x) {if (last[x]) next[last[x]] = next[x];if (next[x]) last[next[x]] = last[x];} void BFS () {while (! Q.empty ()) Q.pop (); Q.push (Next[r1]); INLIST[NEXT[R1] = False;delEte (NEXT[R1]); int x, Y;++top;while (! Q.empty ()) {x = Q.front (); ++sum;++ans[top]; Q.pop (); R2 = n + 2; LAST[R2] = next[r2] = 0;for (Edge *j = point[x]; j; j = J-Next) {y = J-v;if (! Inlist[y]) continue;delete (y); Add (R2, y);} for (int i = next[r1]; i; i = Next[i]) {Q.push (i); inlist[i] = false;} NEXT[R1] = next[r2]; LAST[NEXT[R1]] = R1;}} int main () {scanf ("%d%d", &n, &m); int A, b;for (int i = 1; I <= m; ++i) {Read (a); Read (b); Addedge (A, b); Addedge (b, a);} Top = 0; Sum = 0; R1 = n + 1;for (int i = 1; I <= n; ++i) Add (R1, I); for (int i = 1; I <= n; ++i) Inlist[i] = True;while (Sum < N) BFS ();p rintf ("%d\n", top), sort (ans + 1, ans + top + 1), for (int i = 1; I <= Top; ++i) printf ("%d", ans[i]); return 0;}
[Bzoj 1098] [POI2007] office Building biu "list optimization BFs"