#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T> bool maximize(T &a, const T &b){ return (a < b ? a = b, 1 : 0); }
template<class T> bool minimize(T &a, const T &b){ return (a > b ? a = b, 1 : 0); }
#define fi first
#define se second
#define pb push_back
#define ii pair<int, int>
#define all(x) x.begin(), x.end()
#define TASK "nonsense"
/// end of template ///
const int N = 2e3 + 10;
const int P = 2e5 + 10;
const int Q = 2e5 + 10;
const int M = 2e5 + 10;
const int inf = 1e9;
struct Dsu
{
int n,par[M];
Dsu() {}
void init(int _n)
{
n=_n;
for(int i=1;i<=n;++i) par[i]=i;
}
int get(int x)
{
if(x==par[x]) return x;
return par[x]=get(par[x]);
}
bool unite(int x, int y)
{
int s=get(x),t=get(y);
if(s==t) return 0;
par[s]=t;
return 1;
}
} dsu;
struct Edge
{
int u,v,w;
Edge() {}
Edge(int u, int v, int w) : u(u),v(v),w(w) {}
bool operator < (const Edge &S) const
{
return w<S.w;
}
} edge[P];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int n,m,_p,numQuery,numEdge=0,lo[Q],hi[Q],mid[Q],ans[Q],cur[Q],ptr;
char a[N][N];
ii p[P],dp[N][N],query[Q];
queue<ii> q;
bool ok[Q],process[N][N];
bool cmp(int x, int y)
{
return mid[x]<mid[y];
}
void solve()
{
cin>>n>>m>>_p>>numQuery;
for(int i=1;i<=n;++i)
{
string s; cin>>s;
for(int j=1;j<=m;++j) a[i][j]=s[j-1];
}
for(int i=1;i<=_p;++i)
{
int x,y; cin>>x>>y;
dp[x][y]=make_pair(i,0);
q.push(make_pair(x,y));
}
dsu.init(_p);
while(!q.empty())
{
int i=q.front().fi;
int j=q.front().se;
process[i][j]=1;
// cout<<i<<' '<<j<<" "<<dp[i][j].fi<<' '<<dp[i][j].se<<'\n';
q.pop();
for(int k=0;k<4;++k)
{
int i2=i+dx[k];
int j2=j+dy[k];
if(i2>=1 && i2<=n && j2>=1 && j2<=m && a[i2][j2]!='#')
{
if(dp[i2][j2].fi==0)
{
dp[i2][j2]={dp[i][j].fi,dp[i][j].se+1};
q.push({i2,j2});
}
else if(process[i2][j2] && dsu.get(dp[i][j].fi)!=dsu.get(dp[i2][j2].fi))
{
int u=dp[i][j].fi,v=dp[i2][j2].fi;
// cout<<"XXX "<<u<<' '<<v<<" XXX\n";
edge[++numEdge]=Edge(u,v,dp[i][j].se+dp[i2][j2].se);
dsu.unite(u,v);
}
}
}
}
// for(int i=1;i<=numEdge;++i)
// {
// cout<<edge[i].u<<' '<<edge[i].v<<' '<<edge[i].w<<'\n';
// }
// return;
for(int i=1;i<numEdge;++i) if(edge[i].w>edge[i+1].w) return void(cout<<1/0);
for(int i=1;i<=numQuery;++i)
{
cin>>query[i].fi>>query[i].se;
ans[i]=inf;
lo[i]=1;
hi[i]=numEdge;
}
for(int tri=1;tri<=20;++tri)
{
ptr=0;
memset(ok,0,sizeof(ok));
dsu.init(_p);
for(int i=1;i<=numQuery;++i) if(lo[i]<=hi[i])
{
mid[i]=(lo[i]+hi[i])>>1;
cur[++ptr]=i;
}
// break;
sort(cur+1,cur+1+ptr,cmp);
int num=0;
for(int i=1;i<=ptr;++i)
{
int id=cur[i];
while(num<mid[id])
{
++num;
dsu.unite(edge[num].u,edge[num].v);
}
ok[id]=(dsu.get(query[id].fi)==dsu.get(query[id].se));
}
// break;
for(int i=1;i<=numQuery;++i) if(lo[i]<=hi[i])
{
if(ok[i]) ans[i]=edge[mid[i]].w,hi[i]=mid[i]-1;
else lo[i]=mid[i]+1;
}
}
for(int i=1;i<=numQuery;++i) cout<<(ans[i]==inf?-1:ans[i])<<'\n';
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
// freopen(TASK".inp","r",stdin);
// freopen(TASK".out","w",stdout);
int testcase=1;
// cin>>testcase;
while (testcase--)
solve();
return 0;
}
Compilation message (stderr)
bottle.cpp: In function 'void solve()':
bottle.cpp:116:77: warning: division by zero [-Wdiv-by-zero]
116 | for(int i=1;i<numEdge;++i) if(edge[i].w>edge[i+1].w) return void(cout<<1/0);
| ~^~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |