菜鸡的cf之路QAQ
题目大意: 给n*n的地图 有陆地和水.
可以在联通的陆地上任意行走,可以跨越一次河流走到其他陆地上. 花费为
((x_1 - x_2)^2 + (y_1 - y_2)^2)
求A到B的最小花费
思路: n<50
$ n^2 < 2500 $
dfs求A点所在连通集S1 B所在连通集S2 暴力S1的所有点到S2的所有点的最小花费即可
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn = 55;
int mm[maxn][maxn];
int vis[maxn][maxn];
vector<pair<int,int> > s1;
vector<pair<int,int> > s2;
int n;
void dfs1(int x,int y){
if(x<1 || x>n || y<1 || y>n) return ;
if(mm[x][y] || vis[x][y]) return ;
vis[x][y] = 1;
s1.push_back(make_pair(x,y));
dfs1(x+1,y);
dfs1(x,y+1);
dfs1(x-1,y);
dfs1(x,y-1);
}
void dfs2(int x,int y){
if(x<1 || x>n || y<1 || y>n) return ;
if(mm[x][y] || vis[x][y]) return ;
vis[x][y] = 1;
s2.push_back(make_pair(x,y));
dfs2(x+1,y);
dfs2(x,y+1);
dfs2(x-1,y);
dfs2(x,y-1);
}
int cost(pair<int,int> a,pair<int,int> b){
return (a.first-b.first)*(a.first-b.first) + (a.second-b.second)* (a.second-b.second);
}
int main(){
cin >> n;
int x1,y1,x2,y2;
cin >> x1 >> y1 >> x2 >> y2;
char op;
getchar();
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
scanf("%c",&op);
mm[i][j] = op-'0';
}
getchar();
}
dfs1(x1,y1);
if(vis[x2][y2]) {
cout << 0 << endl;
return 0;
}
dfs2(x2,y2);
int ans = 0x3f3f3f3f;
for(int i=0;i<s1.size();++i){
for(int j=0;j<s2.size();++j){
ans = min(ans,cost(s1[i],s2[j]));
}
}
cout << ans << endl;
return 0;
}