JDOJ1100: Fix
Posted tyner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDOJ1100: Fix相关的知识,希望对你有一定的参考价值。
题目大意
给你n个点,其中一些点是固定的,然后还有一些没有固定的,然后问你固定所有点所用的线段的最小长度是多少。
所谓固定,就是形如三角形的情况,就是两个固定的点向一个未固定的点连两条边,就能把未固定的点固定。
数据范围
1 <= n <= 18
分析
感觉这简单的状压长得跟搜索似得
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string.h>
using namespace std;
const int MAX = 19;
const int INF = 2147000047;
inline int read()
char ch = getchar(); int f = 1, x = 0;
while(ch<'0' || ch>'9') if(ch=='-') f = -1; ch = getchar();
while(ch>='0' && ch<='9') x = x*10+ch-'0'; ch = getchar();
return x*f;
int n, sta, is;
double f[1<<MAX];
struct node
double x, y;
arr[MAX];
double juli(double x1, double y1, double x2, double y2)
return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
double min_juli(int s, int j) //当前状态s,新插入点j,返回插入后状态s`的f
double min1 = INF, min2 = INF, tmp;
for(int i = 1; i <= n; i++)
if(s&(1<<(i-1)))
tmp = juli(arr[i].x, arr[i].y, arr[j].x, arr[j].y);
if(tmp <= min1) min2 = min1, min1 = tmp;
else if(tmp < min2) min2 = tmp;
return min1+min2;//暂不考虑 不存在min
void pre()
memset(arr, 0, sizeof(arr));
for(int i = 1; i < (1<<n); i++) f[i] = INF;
sta = 0;
for(int i = 1; i <= n; i++)
arr[i].x = read(), arr[i].y = read(), is = read();
sta |= (is<<(i-1));
f[sta] = 0;
void solve()
int tmp;
for(int i = sta; i < (1<<n); i++) if((i&sta) == sta)
tmp = (~i & ((1<<n)-1));
// printf("i: %d, 取0:%d\n", i, tmp);
for(int j = 1; j <= n; j++) if(tmp&(1<<(j-1)))
// printf("j: %d,插入之后: %d\n", j, i|(1<<(j-1)));
f[i|(1<<(j-1))] = min(f[i|(1<<(j-1))], f[i] + min_juli(i, j));
if(f[(1<<n)-1] >= INF) printf("No Solution\n");
else printf("%.6f\n", f[(1<<n)-1]);
int main()
while(scanf("%d",&n) && n)
pre();
solve();
return 0;
以上是关于JDOJ1100: Fix的主要内容,如果未能解决你的问题,请参考以下文章