codeforces 884E Binary Matrix 并查集,滚动数组
You are given a matrix of size?n?×?m. Each element of the matrix is either 1 or 0. You have to determine the number of connected components consisting of 1's. Two cells belong to the same component if they have a common border, and both elements in these cells are 1's.
Note that the memory limit is unusual!
InputThe first line contains two numbers?n?and?m?(1?≤?n?≤?212,?4?≤?m?≤?214) — the number of rows and columns, respectively. It is guaranteed that?m?is divisible by 4.
Then the representation of matrix follows. Each of?n?next lines contains??one-digit hexadecimal numbers (that is, these numbers can be represented either as digits from?0?to?9?or as uppercase Latin letters from?A?to?F). Binary representation of each of these numbers denotes next?4?elements of the matrix in the corresponding row. For example, if the number?B?is given, then the corresponding elements are?1011, and if the number is?5, then the corresponding elements are?0101.
Elements are not separated by whitespaces.
OutputPrint the number of connected components consisting of 1's.
題意:
超大矩陣超小內(nèi)存求聯(lián)通塊數(shù)量。
題解:
按行掃描,保留上一行的狀態(tài)以及上一行的并查集。
掃描到第i行時(shí)候,把第i行值為1且相鄰的元素加入到并查集中去。
然后根據(jù)上一行的并查集,把第i行與上一行都為1且上下相鄰的元素以上一行的元素的father點(diǎn)為標(biāo)志,做一個(gè)等價(jià)類(lèi)(等價(jià)類(lèi)中包含的元素全都是第i行的)。
等價(jià)類(lèi)中的元素意義是他們都可以通過(guò)i-1行進(jìn)行互聯(lián),然后把他們加入到并查集里面去。
然后新的一行的并查集就建立完成了。
把新的并查集和舊的并查集交換,這樣一直做下去。
代碼:
#include <bits/stdc++.h> using namespace std; typedef pair<int,int> P; const int maxn = (1<<14)+10; int n,m; long long ans = 0; bool *line0,*line1; int mark[maxn]; int *parents[2]; int group[maxn]; P stk[maxn]; int top; inline int find(int *parent,int x){return parent[x] = x == parent[x]?x:find(parent,parent[x]); } inline void join(int *parent,int x,int y){int p1 = find(parent,x),p2 = find(parent,y);if(p1 == p2) return;parent[p1] = p2; } void initp(int *parent){for(int i = 0;i < maxn;++i) parent[i] = i; } int main(){ios_base::sync_with_stdio(0);cin.tie(0);string s;parents[0] = new int[maxn];parents[1] = new int[maxn];line1 = new bool[maxn];line0 = new bool[maxn];memset(line0,0,maxn*sizeof(bool));memset(line1,0,maxn*sizeof(bool));initp(parents[0]); cin>>n>>m;//n = 4096,m = 16384;for(int i = 1;i <= n+1;++i){memset(line0,0,maxn*sizeof(bool));memset(group,-1,sizeof(group));memset(mark,0,sizeof(mark));top = 0;if(i <= n){cin>>s;for(int j = m/4-1;j >= 0;j--){char c;c = s[m/4-1-j];//c = 'F';int num = c<='9'?c-'0':c-'A'+10;line0[4*j+0] = num&1;line0[4*j+1] = (num>>1)&1;line0[4*j+2] = (num>>2)&1;line0[4*j+3] = (num>>3)&1;}}for(int j = 0;j < m;++j){if(line1[j] && line0[j]) mark[find(parents[0],j)] = 1;}for(int j = 0;j < m;++j){if(line1[j] && !mark[find(parents[0],j)]){ans++;mark[find(parents[0],j)] = 1;}}initp(parents[1]);for(int j = 0;j < m;++j) if(line0[j] && line1[j]){int gp = find(parents[0],j);if(group[gp] == -1) group[gp] = j;else join(parents[1],group[gp],j),group[gp] = j;}for(int j = 0;j < m-1;j++){if(line0[j] && line0[j+1]) join(parents[1],j,j+1);}swap(line1,line0);swap(parents[0],parents[1]);}cout << ans << endl;return 0; }
總結(jié)
以上是生活随笔為你收集整理的codeforces 884E Binary Matrix 并查集,滚动数组的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 任天堂Switch商店上架了计算器,售价
- 下一篇: 软件质量保证划重点期末复习总结