题目:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=90847#problem/C
思路:
经过每条边一次。
递归回溯。
AC.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 10;
int n;
struct node {
int x, y;
}num[maxn];
bool vis[maxn];
int ans[maxn], path[maxn];
double smin;
double dis[maxn][maxn];
void dfs(int u, int snum, double sdis)
{
if(snum == n) {
if(sdis < smin) {
for(int i = 1; i <= n; ++i) {
ans[i] = path[i];
}
smin = sdis;
}
}
for(int v = 1; v <= n; ++v) {
double w = dis[u][v];
if(vis[v]) continue;
vis[v] = 1;
path[snum+1] = v;
dfs(v, snum+1, sdis+w);
vis[v] = 0;
}
}
double cal(node a, node b)
{
return sqrt((double)(a.x-b.x)*(a.x-b.x) + (double)(a.y-b.y)*(a.y-b.y)) + 16.0;
}
void print(int ca)
{
printf("**********************************************************\n");
printf("Network #%d\n", ca);
for(int i = 1; i < n; ++i) {
int u = ans[i], v = ans[i+1];
double w = dis[ans[i]][ans[i+1]];
printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n", num[u].x, num[u].y, num[v].x, num[v].y, w);
}
printf("Number of feet of cable required is %.2lf.\n", smin);
}
int main()
{
//freopen("in", "r", stdin);
int ca = 0;
while(~scanf("%d", &n)) {
if(n == 0) break;
memset(dis, 0, sizeof(dis));
for(int i = 1; i <= n; ++i) {
scanf("%d%d", &num[i].x, &num[i].y);
}
for(int i = 1; i <= n; ++i) {
for(int j = i+1; j <= n; ++j) {
double w = cal(num[i], num[j]);
dis[i][j] = dis[j][i] = w;
}
}
memset(vis, 0, sizeof(vis));
smin = inf;
dfs(0, 0, 0);
ca++;
print(ca);
}
return 0;
}