Codeforces Round #542 div.2 C

菜鸡的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;
}

posted @ 2019-02-25 18:22  新新人類  阅读(125)  评论(0编辑  收藏  举报