有一个n*m的矩阵,矩阵中的元素是八连通的,其中水平和垂直方向的边长是1,自然斜向的边为根号二,现在从某一点出发逐个访问所有元素并放回出发点请问至少要多少才能完成这个任务??
样例:2,3
输出:6.00(保留2位小数)
#include<bits/stdc++.h>
using namespace std;
const int N = 1010,M = N*N,K = 2*N*N;
const double sq2 = 1.414;
int n,m;
int ids[N][N];
struct Node{
int a,b;
double w;
}e[K];
int p[M];
int k;
int find(int x){
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
void get_edges(){
int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
double dw[8] = {sq2,1,sq2,1 ,sq2,1,sq2,1};
for(int z = 0; z < 2; z++){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
for(int u = 0; u < 8; u++){
if(u %2 != z){
cout << dw[u] << " ";
int x = i+dx[u],y = j+dy[u];
double w = dw[u];
if(x && x <= n && y && y <= m){
int a = ids[i][j],b = ids[x][y];
if(a < b){
e[k++] = {a,b,w};
}
}
}
}
}
}
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n*m; i++) p[i] = i;
for(int i = 1,t = 1; i <= n; i++){
for(int j = 1; j <= m; j++,t++){
ids[i][j] = t;
}
}
double res = 1;
get_edges();
for(int i = 0; i < k; i++){
int a = find(e[i].a),b = find(e[i].b);
double w = e[i].w;
if(a != b){
p[a] = b;
res += w;
}
}
printf("\n%0.2lf",res);
return 0;
}