您的位置:首页 > 其它

POJ 1873 The Fortified Forest 二进制枚举 + 凸包 (final水题)

2013-08-29 10:35 363 查看
RT,注意考虑凸包点数小于3的情况




View Code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

#define eps 1e-8
#define inf 1<<29

struct point
{
int x, y;
point(){}
point(int xx, int yy) : x(xx), y(yy){}
};

struct data
{
int x, y, v, l;
}d[16];

int det(int x1, int y1, int x2, int y2)
{
return x1 * y2 - x2 * y1;
}

int cross(point o, point a, point b)
{
return det(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y);
}

double f(int x)
{
return x * x * 1.0;
}

double dis(point a, point b)
{
return sqrt( f(a.x - b.x) + f(a.y - b.y) );
}

int min_v, min_n;
int n, m;
bool vis[17];
int con[17];

bool cmp(point a, point b) //水平序
{
if(a.y == b.y) return a.x < b.x;
return a.y < b.y;
}

double graham(point p[], int n, int len) //返回剩余的长度
{
if(n == 0 || n == 1) return len * 1.000;
if(n == 2) return len * 1.000 - 2 * dis(p[0], p[1]);
int i;
sort(p, p + n, cmp);
int top = 0;
point res[17];
for(i = 0; i < n; i++)
{
while(top >= 2 && cross(res[top-2], res[top-1], p[i]) < 0)
top--;
res[top++] = p[i];
}
int t = top + 1;
for(i = n - 2; i >= 0; i--)
{
while(top >= t && cross(res[top-2], res[top-1], p[i]) < 0)
top--;
res[top++] = p[i];
}
double ans = 0;
for(i = 0; i < top - 1; i++)
ans += dis(res[i], res[i+1]);
return len * 1.000 - ans;
}
int main()
{
int i, j, ca = 1;
int val, num, tree, len, x;
//损失的价值val, 没砍掉的树的个数num,砍掉的树的个数tree
//砍掉一些树所能用的长度len, 最小砍掉树的个数x
double rest;
// 剩余量rest
point pp[17];
while ( ~scanf("%d", &n) && n)
{
for(i = 0; i < n; i++)
scanf("%d%d%d%d", &d[i].x, &d[i].y, &d[i].v, &d[i].l);

min_n = n+1; min_v = inf; rest = 0;

for(i = 0; i < (1<<n); i++)
{
len = val = num = tree = 0;
for(j = 0; j < n; j++)
{
vis[j] = 0;
if( i & (1<<j))
{
val += d[j].v;
len += d[j].l;
tree++;
vis[j] = 1;
}
else pp[num++] = point(d[j].x, d[j].y);
}
if(val > min_v || ( val == min_v && min_n <= tree) )continue;
if(len == 0 && num != 1) continue;

double ans = graham(pp, num, len);
if(ans >= 0)
{
min_v = val;
min_n = tree;
rest = ans;
x = 0;
for(j = 0; j < n; j++)
if(vis[j]) con[x++] = j;
}
}
printf("Forest %d\nCut these trees:", ca++);
for(j = 0; j < x; j++)
printf(" %d", con[j]+1);
printf("\nExtra wood: %.2f\n\n", rest);
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: