Codeforces 1130C

求从(r1,c2)到(r2,c2) 的最小花费,连通的0可以任意走,否则要搭桥,搭桥的费用是两点的欧几里得距离,bfs两次,分别把和(r1,c1)、(r2,c2)相连的0打上标记,n<=50,因此可以n^4枚举。

#include
using namespace std;
#define forn(i,n) for(int i = 0;i P;
queue

q; int dou(int x){ return x*x; } int bfs(int x,int y,int o){ while(!q.empty()) q.pop(); q.push({x,y}); if(o == 1) vis1[x][y] = 1; else vis2[x][y] = 1; while(!q.empty()){ P u = q.front();q.pop(); int nowx= u.first,nowy = u.second; for(int i = 0;i<4;i++){ int nx = nowx + dx[i],ny = nowy+dy[i]; if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&a[nx][ny] == '0'&& ((o==1&&!vis1[nx][ny])||(o==2&&!vis2[nx][ny]))){ if(o == 1)vis1[nx][ny] = 1; else vis2[nx][ny] = 1; q.push({nx,ny}); } } } return 0; } int main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); cin>>n; cin>>r1>>c1>>r2>>c2; for(int i = 1;i<=n;i++) cin>>a[i]+1; bfs(r1,c1,1); bfs(r2,c2,2); for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++) if(vis1[i][j]) for(int k = 1;k<=n;k++) for(int l = 1;l<=n;l++) if(vis2[k][l]) ans = min(ans,dou(i-k)+dou(j-l)); cout<

你可能感兴趣的:(搜索)