POJ 1873 - The Fortified Forest 凸包 + 搜索 模板

通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命..

这题 N = 15

1 << 15 = 32768 直接枚举完全可行

卡在异常情况判断上很久,只有 顶点数 >= 2,即 n >= 3 时凸包才有意义

顶点数为 1 时,tmp = - 1 要做特殊判断。

总结了一下凸包模板

//template Convex Hull

friend bool operator < (const point &p1, const point &p2){
    return (p1.x < p2.x)||(p1.x == p2.x)&&(p1.y < p2.y);
}

void BBS(point p[], int n){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < i; j++){
            if (p[i] < p[j])
                swap(p[i], p[j]);
        }
    }
}

void Convex_Hull(point p[], int n){
    BBS(p, n);    //先按横坐标升序排序,保证p[0]在凸包上
	cur = 0;
	while (1){
	    int tmp = - 1;
	    for (int i = 0; i < n; i++){
	        if (i != cur){
	            if (!(tmp + 1)||(((p[cur] >> p[i]) ^ (p[cur] >> p[tmp])) > 0))
	                tmp = i;
	        }
	    }
	    if (tmp + 1){
	        //找到凸包上的点p[tmp]
	    }
	    if (!tmp||!(tmp + 1)) break;
	    cur = tmp;
	}
}

POJ1873.cpp

//POJ1873
//DFS + 凸包
//注意规避异常状况
//if (tmp + 1)
//  d += (p[cur] >> p[tmp]).norm();
//写代码不认真,出现了许多错误,务必注意
//AC 2016-10-14

#include "cstdio"
#include "cstdlib"
#include "cmath"
#include "iostream"
#define MAXN 20

double sqr(double x){
    return x * x;
}

struct point{
    int x, y, v, l;
    bool cut;
    point(){}
    point(int X, int Y): x(X), y(Y), cut(0){}
    friend point operator >> (const point &p1, const point &p2){
        return point(p2.x - p1.x, p2.y - p1.y);
    }
    friend int operator ^ (const point &p1, const point &p2){
        return p1.x * p2.y - p1.y * p2.x;
    }
    double norm(){
        return sqrt(sqr(x) + sqr(y));
    }
    friend bool operator < (const point &p1, const point &p2){
        return (p1.x < p2.x)||(p1.x == p2.x)&&(p1.y < p2.y);
    }
    friend bool operator > (const point &p1, const point &p2){
        return (p1.x > p2.x)||(p1.x == p2.x)&&(p1.y > p2.y);
    }
}pt[MAXN], p[MAXN], ans[MAXN];

int m0, minval, n, val, len;
double det;

void GetPoints(point src[], point dest[], int n, int &m){
    m = 0;
    for (int i = 0; i < n; i++){
        if (!src[i].cut){
            dest[m++] = src[i];
        }
    }
}

template <class T>
void swap(T &x, T &y){
    T z = x;
    x = y;
    y = z;
}

void BBS(point p[], int n){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < i; j++){
            if (p[i] < p[j])
                swap(p[i], p[j]);
        }
    }
}

void dfs(int x){
    if (!(x + 1)){
        int cur = 0, m, l = len;
        double d = 0, v = val;
        GetPoints(pt, p, n, m);
        BBS(p, m);
        for (int i = 0; i < m; i++){
            v -= p[i].v;
            l -= p[i].l;
        }
        while (1){
            int tmp = - 1;
            for (int i = 0; i < m; i++){
                if (i != cur){
                    if (!(tmp + 1)||(((p[cur] >> p[i]) ^ (p[cur] >> p[tmp])) > 0))
                        tmp = i;
                }
            }
            if (tmp + 1)
                d += (p[cur] >> p[tmp]).norm();
            if (!tmp||!(tmp + 1)) break;
            cur = tmp;
        }
        if (d > l) return;
        if ((v < minval)||(v == minval)&&(m < m0)){
            minval = v, det = l - d, m0 = m;
            for (int i = 0; i < n; i++)
                ans[i] = pt[i];
        }
    }
    else{
	    pt[x].cut = 0;
	    dfs(x - 1);
	    pt[x].cut = 1;
	    dfs(x - 1);
    }
}

int main(){
    int irr = 0;
    freopen("fin.c", "r", stdin);
    while(scanf("%d", &n), n){
        val = len = 0, irr++, det = 0;
        m0 = 0x7f7f7f7f, minval = 0x7f7f7f7f;
        for (int i = 0; i < n; i++){
            scanf("%d%d%d%d", &pt[i].x, &pt[i].y, &pt[i].v, &pt[i].l);
            val += pt[i].v, len += pt[i].l;
        }
        dfs(n - 1);
        if (irr > 1) puts("");
        printf("Forest %d\n", irr);
        printf("Cut these trees:");
        for (int i = 0; i < n; i++){
            if (ans[i].cut)
                printf(" %d", i + 1);
        }
        printf("\nExtra wood: %.2f\n", det);
    }
}
时间: 2024-10-11 23:19:26

POJ 1873 - The Fortified Forest 凸包 + 搜索 模板的相关文章

poj 1873 The Fortified Forest(凸包)

The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5737   Accepted: 1636 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been

Poj 1873 The Fortified Forest

地址:http://poj.org/problem?id=1873 题目: The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6421   Accepted: 1811 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of r

POJ 1873 The Fortified Forest(凸包+枚举 World Finals 1999啊)

题目链接:http://poj.org/problem?id=1873 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been gathered by his ancestors on their travels. To protect his trees fr

Uva5211/POJ1873 The Fortified Forest 凸包

LINK 题意:给出点集,每个点有个价值v和长度l,问把其中几个点取掉,用这几个点的长度能把剩下的点围住,要求剩下的点价值和最大,拿掉的点最少且剩余长度最长. 思路:1999WF中的水题.考虑到其点的数量最多只有15个,那么可以使用暴力枚举所有取点情况,二进制压缩状态,预处理出该状态下的价值,同时记录该状态拥有的点,并按价值排序.按价值枚举状态,并对拥有的这些点求凸包,check是否合法,找到一组跳出即可.然而POJ似乎没有SPJ,同样的代码POJ会超时,UVA60ms,可以在常数上优化,不预处

UVA 811 The Fortified Forest (凸包 + 状态压缩枚举)

题目链接:UVA 811 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been gathered by his ancestors on their travels. To protect his trees from thieves, the king or

poj 1873 凸包+枚举

The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6198   Accepted: 1744 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been

POJ 3528 hdu 3662 三维凸包模板题

POJ 3528题:http://poj.org/problem?id=3528 HDU 3662:http://acm.hdu.edu.cn/showproblem.php?pid=3662 一个是求三维凸包面数,一个是求三维凸包表面积,都是很裸的. 贴代码: #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h>

poj 1873(枚举所有的状态+凸包)

The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6115   Accepted: 1720 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been

POJ 1873

按位枚举,按最小价值,最小砍掉树剪枝就好了. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int MAXN=20; const int inf=190000000; int n,l; int st[MAXN],stop,cnt; int ans[MA