目录
有限点+无限图
题意:给定一个1e6*1e6大小的图,起点、终点、若干(不超200)障碍点,问能否从起点到终点;
传送门
题解:由于图很大,传统bfs肯定不行,先通过证明:与起点(终点同)相连接的点数超过一定阈值则必然联通,可以判断起点终点是否联通。具体证明-by 宫水三叶dalao
bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target) {
#define pii pair<int,int>
set<pii> bok;
for (auto &v : blocked) bok.insert({v[0],v[1]});
int maxn = (bok.size()*bok.size()-bok.size())/2;
int go[4][2] = {0,1,0,-1,1,0,-1,0};
function<bool(pii,pii)> can_go = [&](pii from, pii to){
set<pii> vis;
vis.insert(from);
queue<pii> q;
q.push(from);
while (q.size() && vis.size() <= maxn) {
pii tmp = q.front();
q.pop();
if (tmp == to) return true;
for (int i = 0; i < 4; ++i) {
int xx = tmp.first + go[i][0];
int yy = tmp.second + go[i][1];
if (xx < 0 || yy < 0 || xx >= 1e6 || yy >= 1e6)
continue;
if (bok.count({xx, yy}) || vis.count({xx, yy}))
continue;
q.push({xx, yy});
vis.insert({xx, yy});
cout << xx << ' ' << yy << endl;
}
}
return vis.size() > maxn;
};
pii s = {source[0], source[1]};
pii t = {target[0], target[1]};
return can_go(s, t) && can_go(t, s);
}