#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> #include<bitset> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; #define ls (rt<<1) #define rs (rt<<1|1) #define mid (l+r>>1) #define pb(x) push_back(x) #define cls(x, val) memset(x, val, sizeof(x)) #define fi first #define se second #define mp(x, y) make_pair(x, y) #define lowbit(x) (x&(-x)) #define inc(i, l, r) for(int i=l; i<=r; i++) #define dec(i, r, l) for(int i=r; i>=l; i--) const int inf = 0x3f3f3f3f; const int maxn = 250000+10; const double pi = acos(-1.0); const double eps = 1e-7; const int mod = 1e9+7; int n, m; struct Node{ int u, v, w; }edge[maxn<<1]; int tot; int fa[maxn]; int get(int x) { return x==fa[x]?x:fa[x]=get(fa[x]); } bool vis[maxn]; int ancester[maxn]; struct Node1{ int v, next; }node[maxn<<1]; int cnt, head[maxn]; struct Query{ int to, next; int index; }q[100000*2]; int tt, h[maxn]; int answer[maxn]; void add_query(int u, int v, int index){ q[tt].to = v; q[tt].next = h[u]; q[tt].index = index; h[u] = tt++; q[tt].to = u; q[tt].next = h[v]; q[tt].index = index; h[v] = tt++; } void uni(int u, int v){ int fau=get(u), fav=get(v); if(fau!=fav) fa[fau] = fav; } void LCA(int u){ vis[u] = true; ancester[u] = u; for(int i=head[u]; ~i; i=node[i].next){ int v = node[i].v; if(vis[v]) continue; LCA(v); uni(u, v); ancester[get(u)] = u; } for(int i=h[u]; ~i; i = q[i].next){ int v = q[i].to; if(vis[v]){ answer[q[i].index] = ancester[get(v)]; } } } void add_edge(int u, int v) { node[cnt].v=v,node[cnt].next=head[u],head[u]=cnt++; } bool cmp(Node a, Node b){ return a.w>b.w; } void kruskal(){ for(int i=0; i<=n*m; i++) fa[i]=i; cnt=0, memset(head, -1, sizeof(head)); sort(edge, edge+tot, cmp); int bian = 0; for(int i=0; i<tot; i++){ Node temp=edge[i]; int u=temp.u, v=temp.v; int fau = get(u), fav=get(v); if(fau == fav) continue; fa[fau] = fav; add_edge(u ,v), add_edge(v, u); bian++; if(bian == n*m-1) break; } } int d[maxn]; void bfs(int root){ queue<int>que; cls(vis, 0); d[root] = 0; que.push(root); while(!que.empty()){ int tmp = que.front(); que.pop(); if(vis[tmp]) continue; vis[tmp] = true; for(int i = head[tmp]; i != -1;i = node[i].next){ int v = node[i].v; if(vis[v])continue; d[v] = d[tmp] + 1; que.push(v); } } } int lx[maxn], ly[maxn]; void solve(){ int q; int x1, y1, x2, y2; cin>>q; kruskal(); bfs(1); int s, t; cls(h, -1); for(int i=1; i<=q; i++){ cin>>x1>>y1>>x2>>y2; s=m*(x1-1)+y1, t=m*(x2-1)+y2; lx[i] = s, ly[i] = t; add_query(s, t, i); } cls(vis, 0); for(int i=0; i<=n*m; i++) fa[i] =i; LCA(1); for(int i=1; i<=q; i++){ int ans = d[lx[i]]+d[ly[i]]-2*d[answer[i]]; cout<<ans<<"\n"; } } int main() { ios::sync_with_stdio(false); cin>>n>>m; char c1, c2; int w1, w2; tot=0; for(int i=1; i<=n*m; i++){ cin>>c1>>w1>>c2>>w2; if(c1 != 'X') edge[tot].u=i, edge[tot].v=i+m, edge[tot++].w=w1; if(c2 != 'X') edge[tot].u=i, edge[tot].v=i+1, edge[tot++].w=w2; } solve(); return 0; }
|