UVA1331 Minimax Triangulation

版权声明:本文为博主原创文章, 未经博主允许不得转载。 https://blog.csdn.net/bzjr_Log_x/article/details/79949661



  • 给定一个 n 条边的多边形(不一定是凸多边形),用 n3 条线段(线段必须连接多边形上的两点,每条线段都必须在多边形的内部,并且任意两条线段都不能在多边形内相交)把多边形剖分成 n2 个三角形,试找出一个切割方案,使得最大的三角形面积最小。


  • 第一行一个整数 T 表示数据组数。
  • 每组数据的第一行一个整数 n
  • 接下来 n 行,按顺时针或逆时针顺序给出 n 边形的一个点 (x,y)


  • 一个实数,表示最大面积,保留1位小数。

Sample Input

  • 6
    7 0
    6 2
    9 5
    3 5
    0 3
    1 1

Sample Output

  • 9.0


  • 先把点统一处理成逆时针顺序(若用叉积算多边形面积为负数则为顺时针)。
  • f[l][r] 表示从多边形上第 l 个点 Al 到第 r 个点 Ar 之间的区域全部分割成三角形后,最大三角形面积的最小值。
  • 注意因为多边形首尾顺次相接,l 可以大于 r
  • nxt[i]=i+1(1i<n),nxt[n]=1,则 DP 边界为 f[i][nxt[i]]=0
  • 转移为:f[l][r]=min{max{f[l][i], SAlAiAr, f[i][r]}}(AiAr×AiAr>0)
  • 注意题目给出的多边形不一定是凸多边形,可能存在如下情况:
  • 此时 AlAiAr 是不合法的,但同时我们也会发现用叉积计算结果为负数,因此 DP 就只要判断 AiAr×AiAr>0
  • 最后答案为 min{max{f[i][j], f[j][i]}}(ij)
  • 转移顺序不好处理,可用记忆化搜索实现。


#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int Maxn = 0x3f3f3f3f;
const int N = 55;
int nxt[N], f[N][N], n, m, Ans;

struct point
    int x, y;

    point() {}
    point(int X, int Y):
        x(X), y(Y) {}

    friend inline point operator - (const point &a, const point &b) 
        return point(b.x - a.x, b.y - a.y); 

    friend inline int operator * (const point &a, const point &b)
        return a.x * b.y - b.x * a.y;

inline int Max(int x, int y) {return x > y ? x : y;}
inline int Min(int x, int y) {return x < y ? x : y;}
inline void CkMin(int &x, int y) {if (x > y) x = y;}

inline int dp(int l, int r)
    if (f[l][r] != -1) return f[l][r];
    if (r == nxt[l]) return f[l][r] = 0;
    int res = Maxn;
    for (int i = nxt[l]; i != r; i = nxt[i])
        int tmp = (a[i] - a[r]) * (a[i] - a[l]);
        if (tmp > 0) CkMin(res, Max(Max(dp(l, i), tmp), dp(i, r)));
    return f[l][r] = res;

int main()
    while (scanf("%d", &m) != EOF) 
        while (m--) 
            scanf("%d", &n);
            for (int i = 1; i <= n; ++i) 
                scanf("%d%d", &a[i].x, &a[i].y);
            for (int i = 1; i < n; ++i)
                nxt[i] = i + 1; nxt[n] = 1;
            int sum = 0; 
            for (int i = 1; i < n; ++i)
                sum += a[i] * a[i + 1]; sum += a[n] * a[1];
            if (sum < 0)
                for (int i = 1, im = n >> 1; i <= im; ++i) 
                    swap(a[i], a[n - i + 1]);

            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)
                    f[i][j] = -1;
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)    
                    if (i != j) dp(i, j);
            Ans = Maxn;
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)
                    if (i != j) CkMin(Ans, Max(f[i][j], f[j][i]));
            printf("%.1lf\n", (double)Ans / 2.0);
    return 0;

Minimax Triangulation


Problem DescriptionnTriangulation of surfaces has applications in the Finite Element Method of solid mechanics. The objective is to estimate the stress and strain on complex objects by partitioning them into small simple objects which are considered incompressible. It is convenient to approximate a plane surface with a simple polygon, i.e., a piecewise-linear, closed curve in the plane on m distinct vertices, which does not intersect itself. A chord is a line segment between two non-adjacent vertices of the polygon which lies entirely inside the polygon, so in particular, the endpoints of the chord are the only points of the chord that touch the boundary of the polygon. A triangulation of the polygon, is any choice of m - 3 chords, such that the polygon is divided into triangles. In a triangulation, no two of the chosen chords intersect each other, except at endpoints, and all of the remaining (unchosen) chords cross at least one of the chosen chords. Fortunately, finding an arbitrary triangulation is a fairly easy task, but what if you were asked to find the best triangulation according to some measure?nnnnFigure I.1: Five out of nine possible triangulations of the example polygon. The leftmost hasnthe smallest largest triangle.n nnInputnOn the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing one positive integer 2 < m < 50, being the number of vertices of the simple polygon. The following m lines contain the vertices of the polygon in the order they appear along the border, going either clockwise or counter clockwise, starting at an arbitrary vertex. Each vertex is described by a pair of integers x y obeying 0 <= x <= 10 000 and 0 <= y <= 10 000.n nnOutputnFor each scenario, output one line containing the area of the largest triangle in the triangulation of the polygon which has the smallest largest triangle. The area should be presented with one fractional decimal digit.n nnSample Inputn1n6n7 0n6 2n9 5n3 5n0 3n1 1n nnSample Outputn9.0n n


  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他