AcWing 4004.传送阵
题目描述
格式
题解
- 题目要求最小的成本,所以我们需要先判断起点到终点是否有通路,可以直接对起点DFS,把所有的联通点存入vector之中,并且可以用
cnt[][]
来存储走过的坐标。 - 如果起点与终点没有通路,我们可以对终点做DFS,找到终点的所有联通点,之后我们可以通过两个
for
循环遍历起点和终点的联通点,找到距离最小的两个点,那么这两个点的成本(欧几里得距离)也就最小。
#include<bits/stdc++.h>
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
#define rg register
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 60;
int n,ans,mp[N][N];
bool cnt1[N][N],cnt2[N][N];
void dfs1(int,int),dfs2(int,int);
PII stp,enp;
vector<PII> st,en;
int main() {
io_opt;
ans = INF;
cin >> n;
cin >> stp.first >> stp.second;
cin >> enp.first >> enp.second;
for(int y = 1;y <= n;y++){
for(int x = 1;x <= n;x++) cin >> mp[y][x];
}
//起点开始dfs
dfs1(stp.first,stp.second);
if(cnt1[stp.first][stp.second]) ans = 0;
else{
dfs2(enp.first, enp.second);
for(int i=0;i<st.size();i++){
for(int j=0;j<en.size();j++){
int k = pow(st[i].first - st[j].first,2) + pow(st[i].second - st[j].second,2);
ans = min(ans,k);
}
}
}
cout << ans << endl;
return 0;
}
void dfs1(int y,int x){
if(mp[y][x] == 1 or cnt1[y][x]) return;
st.push_back(make_pair(y,x));
cnt1[y][x] = true; // 记录
if(y-1>=1) dfs1(x,y-1);
if(y+1<=n) dfs1(x,y+1);
if(x-1>=1) dfs1(x-1,y);
if(x+1<=n) dfs1(x+1,y);
}
void dfs2(int y,int x){
if(mp[y][x] == 1 or cnt2[y][x]) return;
en.push_back(make_pair(y,x));
cnt2[y][x] = true; // 记录
if(y-1>=1) dfs2(x,y-1);
if(y+1<=n) dfs2(x,y+1);
if(x-1>=1) dfs2(x-1,y);
if(x+1<=n) dfs2(x+1,y);
}
2(x,y+1);
if(x-1>=1) dfs2(x-1,y);
if(x+1<=n) dfs2(x+1,y);
}