银牌题,但是有点卡人心态。 time :5s mel :1024mb
题意:给定k<=42个黑洞(黑洞不能经过),n*m<=200000的矩阵,q<=100000次询问,给定x1,y1,x2,y2,问最短路,不存在则-1.
可以说是思路一眼题啊,如果两个点之间(也就是两矩阵之间)没有黑洞的话,直接曼哈顿距离即可,而且这样用矩阵前缀和即可处理。如果有黑洞的话,一定是从所有黑洞相邻的点转移过去(两个距离之和取最小),所以我们要记一个dis的三维数组,大小为k*4*n*m,最大4e7左右,所以这个数组要定义在外面,所以就用到了int ***dis +new 动态开内存,每个dis 数组可以用bfs求得。
口胡一下:如果把二维矩阵转为一维2e5,然后搞一个坐标对应函数也可以吧~~~
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
typedef long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
typedef unsigned long long ull;
typedef unsigned short us;
const int INF= 1e9+7;
const ll maxn = 2e6+7;
const ll maxx = 2e6+7;
const ll mod= 998244353;
inline bool read(int &num)
{char in;bool IsN=false;
in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
int n,m,p,k,q;
int dx[5]={0,0,-1,1};
int dy[5]={-1,1,0,0};
int x[maxx],y[maxx];
int ***dis;
int main(){
ll Q;
cin>>n>>m>>k>>Q;
int a[n+5][m+5];
int sum[n+5][m+5];
memset(a,0,sizeof(a));
memset(sum,0,sizeof(sum));
bool vis[n+5][m+5];
rep(i,1,k)
{
read(x[i]);read(y[i]);
a[x[i]][y[i]]=1;
}
rep(i,1,n)
rep(j,1,m)
{
sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
}
ll geshu=0;
memset(vis,0,sizeof(vis));
rep(i,1,k)
{
rep(j,0,3)
{
int px=x[i]+dx[j];
int py=y[i]+dy[j];
// printf("%lld %lld\n",px,py);
if(a[px][py]==0&&px>=1&&px<=n&&py>=1&&py<=m )
{
geshu++;
}
}
}
dis= new int **[k*4-2];
rep(i,1,geshu+2)
{
dis[i]=new int*[n+5];
rep(j,1,n)
dis[i][j]=new int[m+5];
}
rep(i,1,geshu)
rep(j,1,n)
rep(k,1,m) dis[i][j][k]=-1;
int cnt=0;
rep(i,1,k)
{
rep(j,0,3)
{
memset(vis,0,sizeof(vis));
int px=x[i]+dx[j];
int py=y[i]+dy[j];
// printf("%lld %lld\n",px,py);
if(a[px][py]==0&&px>=1&&px<=n&&py>=1&&py<=m)
{
++cnt;
dis[cnt][px][py]=0;
queue<pair<int,int> >q;
q.push(make_pair(px,py));
vis[px][py]=1;
while(!q.empty())
{
int x=q.front().first;
int y=q.front().second;
int juli=dis[cnt][x][y];
//printf("%d %d\n",x,y);
q.pop();
rep(l,0,3)
{
ll qx=x+dx[l];
ll qy=y+dy[l];
if(!vis[qx][qy]&&a[qx][qy]==0&&qx>=1&&qx<=n&&qy>=1&&qy<=m)
{
dis[cnt][qx][qy]=juli+1;
vis[qx][qy]=1;
q.push(make_pair(qx,qy));
}
}
}
}
}
}
rep(i,1,Q)
{
int x1,y1,x2,y2;
read(x1);read(y1);read(x2);read(y2);
int p1=min(x1,x2);
int p3=min(y1,y2);
int p2=max(x1,x2);
int p4=max(y1,y2);
// cout<<sum[p2][p4]-sum[p1-1][p4]-sum[p2][p3-1]+sum[p1-1][p3-1]<<endl;
if(a[x1][y1]==1||a[x2][y2]==1) {
// printf("wdqqwd\n");
printf("-1\n");
}
else if(sum[p2][p4]-sum[p1-1][p4]-sum[p2][p3-1]+sum[p1-1][p3-1] == 0)
{
int ans=y1-y2;
printf("%d\n",abs(x1-x2)+abs(ans));
}
else
{
int minl=INF;
rep(i,1,cnt)
{
if(dis[i][x1][y1]!=-1&&dis[i][x2][y2]!=-1)
{
minl=min(minl,dis[i][x1][y1]+dis[i][x2][y2]);
}
}
if(minl==INF) printf("-1\n");
else printf("%d\n",minl);
}
}
return 0;
}
/***
5 5 8 100
2 2
2 3
2 4
3 2
3 4
4 2
4 3
4 4
***/
B Labyrinth
Due to the challenging problems, some of the contestants decide to escape from this contest. However, to prevent this from happening, the EVIL problem setters made a labyrinth at the stadium's exit. The labyrinth is made of an n×m grid, on which lie the entrance and the exit, and k black holes. Contestants who accidentally step into any black hole will fall into it and thus can never escape from the contest.
What's worse, the problem setters may also adjust the coordinates of the entrance and the exit. You, a poor contestant, who start from the entrance and wish to reach the exit without stepping into any of the black holes, can only move to one of the four adjacent cells in each step. You want to know, after each time the problem setters change the coordinates of the entrance and the exit, what's the minimum number of steps needed to reach the exit starting from the entrance?
Input Specification:
The first line of the input contains four integers n,m,k,q (1≤n,m≤200000,nm≤200000,0≤k≤42, 1≤q≤100000), denoting the number of rows, the number of columns, the number of black holes in the labyrinth, and the number of queries, respectively.
The following k lines contain the description of the black holes. Each of these lines contains two integers x,y (1≤x≤n,1≤y≤m), denoting the coordinates of a black hole. No two black holes are located at the same position.
The last q lines contain the description of the queries. Each of the q lines contains four integers xs,ys,xt,yt (1≤xs,xt≤n,1≤ys,yt≤m), where (xs,ys) is the coordinates of the entrace and (xt,yt) is the exit.
Output Specification:
For each query, output a number in a line, denoting the minimum number of steps needed to reach the exit starting from the entrance. If it is impossible to reach the exit, output -1
instead. It should be considered impossible when the entrace or the exit coincides with a black hole.
Sample Input 1:
5 5 4 7
2 2
2 3
3 2
3 3
2 1 3 4
1 1 1 1
2 2 2 2
1 1 1 5
2 2 5 5
2 1 2 4
1 1 3 3
Sample Output 1:
6
0
-1
4
-1
5
-1
Sample Input 2:
2 3 2 1
1 2
2 1
1 1 2 3
Sample Output 2:
-1
Notes:
The plots for the labyrinth and the first query of the first sample data are shown below.
Figure 1: Plots for sample test data