您的位置:首页 > 其它

并查集·UVA 1665·Islands

2018-03-08 11:47 190 查看
题目大意:
给定n*m的矩阵,格子中的数均<1e9;
在给定t个数,求格子中≥ti的数所组成的四连通块有几个。
解题思路:
这题使用了并查集求联通块,这个题目如果从图中一个一个找出肯定超时,但是如
4000
果根据一个格子的上下左右增添联通块,那会简单的多(至少不用遍历这张图了),具体做法:
我们给格子中的每个数按照权值大小排好顺序,并且从大到小取ti,因为这样,再将大于某一值res的联通块已经将所有格子都用过,那么我们并不需要再往下找了,整个图就是一个联通块,直接将剩下的赋值为1就好了。
剩下要做的就是从大到小的取出格子中的数,依次增添联通块。
网上有个代码中有这样一种操作;
!~p,,,,,,,,,,,,这TM不就是 p == -1 嘛,有毒吧,,在时间上能节约很大嘛???
AC代码:#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;
#define maxn 100000 + 7
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(x,y) memset(x,y,sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define pii pair<int,int>
//#define mp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = (ll)1e18+300;
int mapp[1010][1010];
int n, m;
int fa[1010*1010];
int tt[maxn];
int dire[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};

struct Node{
int x, y;
int val;
}node[1010*1010];
int find(int x){
if(fa[x] != x) {
fa[x] = find(fa[x]);
}
return fa[x];
}

bool cmp(Node a, Node b) {
return a.val < b.val;
}

bool judge(int x,int y, int c) {
if(x >= 0 && x < n && y >= 0 && y < m && mapp[x][y] > c) {
return true;
}
return false;
}

int main() {
int t;
cin >> t;
while(t -- ) {
ms(fa, -1);
cin >> n >> m;
int pos = 0;
for (int i = 0; i < n; i++){
for (int j = 0 ; j < m; j ++) {
cin >> mapp[i][j];
//pos = i * m + j;
node[pos].x = i;
node[pos].y = j;
node[pos++].val = mapp[i][j];
}
}
sort(node, node+n*m, cmp);

int t;
cin >> t;
for (int i = 0; i < t; i++) {
cin >> tt[i];
}
int len = n*m - 1;
int ans = 0;
for (int i = t-1; i >= 0; i--) {
if(tt[i] < node[len].val) {
while(len >= 0 && tt[i] < node[len].val) {
int pos = node[len].x * m + node[len].y;
if(fa[pos] == -1) {
fa[pos] = pos;
ans ++;
}
for (int j = 0; j < 4; j++){
int dx = node[len].x + dire[j][0];
int dy = node[len].y + dire[j][1];
if(judge(dx, dy, tt[i])) {
int pos1 = dx * m + dy;
if(fa[pos1] != -1) {
int u = find(pos);
int v = find(pos1);
if(u != v) {
fa[u] = v;
ans --;
}
}
}
}
len --;
}
if(len < 0 ) {
while(1) {
if(i < 0) {
break;
}
tt[i--] = 1;
}
break;
}
}
tt[i] = ans;
}
for (int i = 0 ;i < t; i++) {
cout << tt[i] << " ";
}
cout << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: