首页 > 其他分享 >最大面积最小的三角剖分 Minimax Triangulation

最大面积最小的三角剖分 Minimax Triangulation

时间:2022-12-17 22:44:18浏览次数:45  
标签:return 剖分 int Minimax db Triangulation vec mistake vecs

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define mistake(P) ( fabs ( P ) < eps ? 0 : (P < 0 ? -1 : 1) ) // 精度误差判断正负
#define db double
#define vec point
const db eps = 1e-10;
struct point {
	db x , y ;
	point ( db X = 0 , db Y = 0 ) : x ( X ) , y ( Y ) {}
};
vec operator + ( vec x , vec y ) { return vec ( x . x + y . x , x . y + y . y ) ; }
vec operator - ( vec x , vec y ) { return vec ( x . x - y . x , x . y - y . y ) ; }
vec operator * ( vec x , db y ) { return vec ( x . x * y , x . y * y ) ; }
bool operator == ( vec x , vec y ) { return mistake ( x . x - y . x ) == 0 and mistake ( x . y - y . y ) == 0 ; }
db dot_product ( vec x , vec y ) { return x . x * y . x + x . y * y . y ; }
db cross_product ( vec x , vec y ) { return x . x * y . y - x . y * y . x ; }
db length ( vec x ) { return sqrt ( dot_product ( x , x ) ) ; }
double areas ( vec x , vec y , vec z ) { return cross_product ( y - x , z - x ) ; }
//判断 x 是否在 a , b 中间。
bool zzj ( point x , point a , point b ) {
	return 
		mistake ( cross_product ( a - x , b - x ) ) == 0 
	and 
		mistake ( dot_product ( a - x , b - x ) ) < 0 ; 
}
//运用叉积计算 x2 , y2 在 向量 x1 -> y1 and x2 -> y2 的两侧 来判断向量是否相交。
bool pdxj ( point x1 , point y1 , point x2 , point y2 ) {
	db a = cross_product ( y1 - x1 , x2 - x1 ) , b = cross_product ( y1 - x1 , y2 - x1 ) ;
	db c = cross_product ( y2 - x2 , x1 - x2 ) , d = cross_product ( y2 - x2 , y1 - x2 ) ; 
	return mistake ( a ) * mistake ( b ) < 0 and mistake ( c ) * mistake ( d ) < 0 ;
}
bool pdzdbxn ( vector<vec> & vecs , vec cx ) {
	int num = vecs . size() , flag = 0 ;
	for ( int i = 0 ; i < num ; i ++ ){
		vec x = vecs [ i ] , y = vecs [ ( i + 1 ) % num ] ;
		if ( x == cx || y == cx || zzj ( cx , x , y ) ) return false;
		int k = mistake ( cross_product ( y - x , cx - x ) ) ;
		int a = mistake ( x . y - cx . y ) ;
		int b = mistake ( y . y - cx . y ) ;
		if ( k > 0 and a <= 0 and b > 0 ) flag ++ ;
		if ( k < 0 and b <= 0 and a > 0 ) flag -- ;
	}
	if ( flag != 0 ) return true;
	return false;
}
bool zdbxn ( vector<vec> & vecs , int x , int y ) {
	int num = vecs . size();
	for ( int i = 0 ; i < num ; i ++ ) {
		if ( i == x and i == y ) continue;
		if ( zzj ( vecs [ i ] , vecs [ x ] , vecs [ y ] ) ) return false ;
	}
	for ( int i = 0 ; i < num ; i ++ ) {
		if ( pdxj ( vecs [ i ] , vecs [ ( i + 1 ) % num ] , vecs [ x ] , vecs [ y ] ) ) return false ;
	}
	vec adds = vecs [ x ] + vecs [ y ] ;
	adds = adds * 0.5 ; 
	return pdzdbxn ( vecs , adds ) ; 
}
db f [ 100 ] [ 100 ] ;
void dp ( vector<vec> & vecs ) {
	int n = vecs . size();
	for ( int i = 0 ; i < n ; i ++ ) 
		for ( int j = 0 ; j < n ; j ++ ) 
			f [ i ] [ j ] = -1 ;
	for ( int len = 2 ; len <= n ; len ++ ) {
		for ( int i = 0 ; i + len - 1 < n ; i ++ ) {
			int j = i + len - 1 ;
			if ( j == i + 1 ) { f [ i ] [ j ] = 0 ; continue ; }
			if ( ! ( i == 0 and j == n - 1 ) and ! zdbxn ( vecs , i , j ) ) { f [ i ] [ j ] = 100000000.00 ; continue; }
			f [ i ] [ j ] = 100000000.00 ;
			for ( int k = i + 1 ; k < j ; k ++ ) {
				db work = fabs ( cross_product ( vecs [ j ] - vecs [ i ]  ,  vecs [ k ] - vecs [ i ] ) ) / 2.000;
				f [ i ] [ j ] = min ( f [ i ] [ j ] , max ( f [ i ] [ k ] , max ( f [ k ] [ j ] , work ) ) ) ;
			}
		}
	}
	printf ( "%.1lf\n" , f [ 0 ] [ n - 1 ] ) ;
}
int work () {
	vector<vec> vecs;
	int n ; cin >> n ;
	for ( int i = 0 ; i < n ; i ++ ) {
		static db x , y ; 
		scanf ( "%lf%lf" , & x , & y ) ;
		vecs . push_back ( vec ( x , y ) ) ;
	}
	dp(vecs);
	return 0 ;
}
int main(){
    int T ; cin >> T ;
    while ( T -- ) work();
}

标签:return,剖分,int,Minimax,db,Triangulation,vec,mistake,vecs
From: https://www.cnblogs.com/dadidididi/p/16989763.html

相关文章

  • 边权树链剖分
    边权树链剖分一般的树链剖分都是维护的点权,而如果要维护边权怎么办呢?思路我们可以把边权转换为点权。一个点有很多个儿子,但只有一个父亲。如果一个节点的点权记录到其儿......
  • 重链剖分学习笔记
    最近在机房自习复习了一下这些东西,主要给自己看的。参考文献:OIWiki《算法竞赛》(罗勇军,郭卫斌著)1重链剖分简介1.1重链剖分基本性质树链剖分,就是把树分成若......
  • 重链剖分学习笔记
    最近在机房自习复习了一下这些东西,主要给自己看的。参考文献:OIWiki《算法竞赛》(罗勇军,郭卫斌著)1重链剖分简介1.1重链剖分基本性质树链剖分,就是把树分成若......
  • 树链剖分学习笔记
    树链剖分学习笔记简介树链剖分是一种可以把树丢到线段树上维护的一种算法,时间复杂度为\(O(n\log^2n)\)。思路一、一些概念1.重儿子:如果一个点有儿子,那么所有儿子中......
  • P3128 [USACO15DEC]Max Flow P(树上倍增和树链剖分)
    思路1(树上倍增$+$树上差分)每次都修改一条从\(u\)到\(v\),不就是树上差分的专门操作吗??直接用倍增求\(LCA\),每次\(d[u]++,d[v]++,d[LCA(u,v)]--,d[f[LCA(u,v)][0]]--\)。......
  • 浅谈树链剖分
    树链剖分定理重儿子:一个节点所有儿子中,子树大小最大的儿子即为重儿子,如有多个,任取一个即可。轻儿子:除了重儿子外的所有儿子。重边:父节点\(\to\)重儿子的边。重链:由......
  • 树链剖分
    树链剖分0x00绪言在阅读这篇文章前,确保你已学会你下内容:线段树深度优先遍历会了这些就可以开始阅读本篇文章了。0x01什么是树剖把一棵树拆成若干个不相交的链,然......
  • 浅析树链剖分
    可以看出树链剖分的作用就是将一棵树变成一个可处理的dfs序,树上操作一般由​​线段树​​来维护,看一下模板题​​BZOJ1036​​和​​POJ3237​​。......
  • 博弈论与强化学习 一 Minimax Q, Nash Q ,FFQ
    博弈解与强化学习二基础算法2.1引言一个随机博弈可以看成是一个多智能体强化学习过程,但其实这两个概念不能完全等价,随机博弈中假定每个状态的奖励矩阵是已知的,不需要......
  • 树链剖分学习笔记(补发)
    求大佬指错QaQ个人推荐的题单:树链剖分练习题个人感觉树链剖分就是把树上的节点按照某种顺序重新编号一次以便于用线段树、树状数组等维护。这次讲讲轻重链剖分。模板题......