原题链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2300
给你一个图,让你生成一个完全子图。使得这个子图中每个点的最小边的和最大。。好拗口,但是就是这么回事。。
就直接dfs就好,搜啊搜啊,就做出来了。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define MAX_N 20 #define MAX_S 1<<20 using namespace std; double dp[MAX_S]; double L[MAX_N],a[MAX_N],b[MAX_N]; int N,M; int getOnes(int s) { int res = 0; while (s) { if (s & 1)res++; s >>= 1; } return res; } bool vis[MAX_S]; double dis(int i,int j) { return (L[i] - L[j]) * (L[i] - L[j]) + (a[i] - a[j]) * (a[i] - a[j]) + (b[i] - b[j]) * (b[i] - b[j]); } void dfs(int s) { for (int i = 0; i < N; i++) { if ((1 << i) & s)continue; int t = (1 << i) | s; if (vis[t])continue; vis[t] = 1; double sum = 0; for (int j = 0; j < N; j++) if ((1 << j) & s) sum += dis(i, j); dp[t] = dp[s] + sum; dfs(t); } } int main() { scanf("%d%d", &N, &M); for (int i = 0; i < N; i++) scanf("%lf%lf%lf", &L[i], &a[i], &b[i]); dfs(0); double ans = 0; for (int i = 0; i < (1 << N); i++) if (getOnes(i) == M) ans = max(ans, dp[i]); printf("%.5f\n", ans); return 0; }
原文:http://www.cnblogs.com/HarryGuo2012/p/4851636.html