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;
}

猜你喜欢

转载自www.cnblogs.com/xxrlz/p/10432510.html