Coconuts HDU - 5925 (bfs + 离散化)
题目链接:https://cn.vjudge.net/contest/221692#problem/D
题目大意:就是有r*c的方阵 上面都是白的 其中有n个黑色的点 ,问你黑色的点把白色的点分成了几个部分,每个部分的点有多少。
input:
2
3 3
2
1 2
2 1
3 3
1
2 2
output:
Case #1:
2
1 6
Case #2:
1
8
题目分析:正常的思路就是搜索,但是图太大 0 < R,C≤ 1e9, 会超时, 可是黑色的点少啊,才200,所以突破点应该就在这里。
最终想出用离散化的方法解决这个问题,;
图很大的时候每个点之间的距离很大,只要把这一部分离散化就好了,离散化后 图最坏也只是400*400,这样的话搜索就不会超时了。
然而这个题补了这么久就是卡在离散化这里了。不会二维的离散化…
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3000;
typedef long long ll;
int x[maxn], y[maxn], cntx, cnty, tx[maxn], ty[maxn];
ll p[maxn][maxn];
vector<int> data1, data2;
vector<ll> ans;
bool vis[maxn][maxn];
int dict[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
bool judge(int x, int y) {
return x >= 1 && x < cntx && y >= 1 && y < cnty && !vis[x][y];
}
ll bfs(int x, int y) {
queue<pair<int, int> > q;
ll num = 0;
vis[x][y] = true;
q.push(make_pair(x, y));
while(!q.empty()) {
int X = q.front().first;
int Y = q.front().second;
q.pop();
num += p[X][Y];
for(int i = 0; i < 4; i++) {
int tx = X + dict[i][0];
int ty = Y + dict[i][1];
if(judge(tx, ty)) {
vis[tx][ty] = true;
q.push(make_pair(tx, ty));
}
}
}
return num;
}
int main()
{
int t, cas = 1;
scanf("%d", &t);
while(t--)
{
int n, m;
data1.clear();
data2.clear();
memset(vis, false, sizeof(vis));
scanf("%d %d", &n, &m);
int num;
scanf("%d", &num);
data1.push_back(0);
data1.push_back(n);
data2.push_back(0);
data2.push_back(m);
for(int i = 0; i < num; i++)
{
scanf("%d %d", &tx[i], &ty[i]);
for(int d = -1; d <= 1; d++) {
if(tx[i] + d >= 0 && tx[i] + d <= n) data1.push_back(tx[i] + d);
if(ty[i] + d >= 0 && ty[i] + d <= m) data2.push_back(ty[i] + d);
}
}
sort(data1.begin(), data1.end());
sort(data2.begin(), data2.end());
cntx = unique(data1.begin(), data1.end()) - data1.begin();
cnty = unique(data2.begin(), data2.end()) - data2.begin();
for(int i = 1; i < cntx; i++) {
for(int j = 1; j < cnty; j++) {
p[i][j] = (ll)(data1[i] - data1[i - 1]) * (data2[j] - data2[j - 1]);
// printf("%d %d %lld\n", i, j, p[i][j]);
}
}
//p[i][j]表示(i, j)这个点表示的实际的点的个数
for(int i = 0; i < num; i++) {
int u = lower_bound(data1.begin(), data1.begin() + cntx, tx[i]) - data1.begin();
int v = lower_bound(data2.begin(), data2.begin() + cnty, ty[i]) - data2.begin();
vis[u][v] = true;
}
// for(int i = 1; i < cntx; i++) {
// for(int j = 1; j < cnty; j++) {
// printf("%d%c", vis[i][j], j == cnty - 1 ? '\n' : ' ');
// }
// }
// printf("\n");
ans.clear();
for(int i = 1; i < cntx; i++) {
for(int j = 1; j < cnty; j++) {
if(!vis[i][j]) {
ans.push_back(bfs(i, j));
}
}
}
printf("Case #%d:\n", cas++);
printf("%d\n", ans.size());
sort(ans.begin(), ans.end());
for(int i = 0; i < ans.size(); i++)
printf("%lld%c", ans[i], i == ans.size() - 1 ? '\n' : ' ');
}
}