您的位置:首页 > 其它

UVA 1331 Minimax Triangulation [最优三角剖分] [dp] [计算几何]

2016-08-23 22:25 519 查看
Minimax Triangulation

Time Limit: 3000MS 64bit IO Format: %lld & %llu





计算几何版的最优三角剖分,同样是dp的基础。

这个要考虑凹多边形的情况,那么此时需要把剖分的三角形做一个判断,判断是否有点在三角形内部。

然而像这样的特殊情况不用单独考虑,因为虽然这种三角形是合法的,但是却不能转移到任何下阶段的状态。

判断三角形内部一开始写了三个叉积的正负性进行比较,然而特殊处理点在边上的时候挂了,因为如果点在边的延长线上,这是合法状态,然而函数却返回在三角形内!!!

那么这时候可以判断三个三角形面积之和与大三角形的关系!!!

最后并不用像合并石子那样循环(学到一种新方法叫取模),因为只考虑1~n就可以涵盖所有情况。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const double INF = 1e100;
const int maxn = 55;
const double eps = 1e-7;
inline int dcmp(double x)
{
if(fabs(x)<eps) return 0;
if(x>0.0) return 1;
else return -1;
}
struct Point
{
double x,y;
}point[maxn];
struct Vector
{
double x,y;
Vector (const double _x,const double _y) { x=_x; y=_y; }
};
Vector operator - (const Point A,const Point B) { return Vector(A.x-B.x,A.y-B.y); }
inline double Dot (const Vector v1,const Vector v2) { return v1.x*v2.x+v1.y*v2.y; }
inline double Cross (const Vector v1,const Vector v2) { return v1.x*v2.y-v2.x*v1.y; }
inline double Area(Point A,Point B,Point C) { return fabs(0.5*(A.x*B.y+B.x*C.y+C.x*A.y-A.x*C.y-B.x*A.y-C.x*B.y)); }
bool PointInTriangle(Point A,Point B,Point C,Point P)
{
double t1=Area(A,B,P),t2=Area(B,C,P),t3=Area(C,A,P);
double tt=Area(A,B,C);
return dcmp(tt-(t1+t2+t3))==0;
}
/*not suitable for cases that P is out of triangle but on the same line!
* bool PointInTriangle(Point A,Point B,Point C,Point P)
{
Vector AB=B-A,BC=C-B,CA=A-C;
Vector AP=P-A,BP=P-B,CP=P-C;
int t1=dcmp(Cross(AB,AP)),t2=dcmp(Cross(BC,BP)),t3=dcmp(Cross(CA,CP));
int tot=t1+t2+t3;
if(!(t1&&t2&&t3)) return true;
return tot==3 || tot==-3;
}
*/
int n;
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf%lf",&point[i].x,&point[i].y);
}
bool BadTriangulation(int a,int b,int c)
{
for(int i=1;i<=n;i++) if(i^a&&i^b&&i^c)
if(PointInTriangle(point[a],point[b],point[c],point[i])) return true;
return false;
}
double dp[maxn][maxn];
double dynamic()
{
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
dp[i][j]=INF;
for(int i=1;i<n;i++) dp[i][i+1]=0.0;
for(int k=3;k<=n;k++)
for(int i=1;i+k-1<=n;i++)
{
int j=i+k-1;
for(int p=i+1;p<j;p++)
if(BadTriangulation(i,j,p)) continue;
else smin(dp[i][j],maxx(dp[i][p],dp[p][j],Area(point[i],point[j],point[p])));
}
return dp[1]
;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("tri.in","r",stdin);
freopen("tri.out","w",stdout);
#endif
int cas;
scanf("%d",&cas);
while(cas--)
{
init();
double ans=dynamic();
printf("%.1lf\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息