1 // ALGORITMO, QUE USA GEMETIA; PARA VER EN UN POLIGONO CONVEXO
2 //Q PUNTOS ESTAN EN Q TRIANGULO Q CONTENGA PUNTOS ADJACENTES
3 // FRONTIER, TIMUS :), costo un ojo de la cara! :P :D
24 #define forn(i, n) for(int i=0;i<int(n);i++)
25 #define foreach(it, c) for(typeof((c).begin()) it = (c).begin();it!=(c).end();++it)
26 #define ALL(x) (x).begin(),(x).end()
27 #define SORT(x) sort(ALL(x))
29 #define VI vector<int>
30 #define VS vector<string>
37 bool fijo
[51][51][51];
38 double cruz(int h
, int i
, int j
){
40 x1
= tow
[i
][0]-p
[h
][0], x2
= tow
[j
][0] - p
[h
][0];
41 y1
= tow
[i
][1]-p
[h
][1], y2
= tow
[j
][1] - p
[h
][1];
42 return fabs((double)x1
*y2
-x2
*y1
)/2.0;
44 double cruz2(int h
, int i
, int j
){
46 x1
= tow
[i
][0]-tow
[h
][0], x2
= tow
[j
][0] - tow
[h
][0];
47 y1
= tow
[i
][1]-tow
[h
][1], y2
= tow
[j
][1] - tow
[h
][1];
48 return fabs((double)x1
*y2
-x2
*y1
)/2.0;
50 bool adentro(int pi
, int i
, int j
, int k
){
51 double a1
= cruz(pi
,i
,j
), a2
= cruz(pi
,i
,k
), a3
= cruz(pi
,j
,k
);
52 if( fabs(a1
+a2
+a3
- cruz2(i
,j
,k
)) < 1e-7 ) return true;
55 double cruz3(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
){
56 double xx1
, xx2
, yy1
, yy2
;
57 xx1
= x2
-x1
, xx2
= x3
-x1
;
58 yy1
= y2
-y1
, yy2
= y3
-y1
;
59 return fabs(xx1
*yy2
-xx2
*yy1
);
61 double dist(double x1
, double y1
, double x2
, double y2
){
65 return sqrt(dx
*dx
+dy
*dy
);
68 vector
<pair
<double, int> > vec
;
70 int ant
= (ind
+N
-1)%N
;
73 x
= (m
[i
][0]-(double)tow
[ind
][0]) / dist(tow
[ind
][0], tow
[ind
][1], m
[i
][0], m
[i
][1]);
74 y
= (m
[i
][1]-(double)tow
[ind
][1]) / dist(tow
[ind
][0], tow
[ind
][1], m
[i
][0], m
[i
][1]);
76 xa
= (tow
[ant
][0]-(double)tow
[ind
][0]) / (dist(tow
[ant
][0], tow
[ant
][1], tow
[ind
][0], tow
[ind
][1]));
77 ya
= (tow
[ant
][1]-(double)tow
[ind
][1]) / (dist(tow
[ant
][0], tow
[ant
][1], tow
[ind
][0], tow
[ind
][1]));
79 d1
= dist( xa
, ya
, x
, y
);
80 d2
= dist(0.0, 0.0, x
, y
);
81 d3
= dist(0.0, 0.0, xa
, ya
);
82 double area
= cruz3(x
, y
, 0.0, 0.0, xa
, ya
);
83 double alt
= area
/ d3
;
84 double len
= sqrt(d2
*d2
-alt
*alt
);
85 if( d1
*d1
+ 1e-7 > d2
*d2
+d3
*d3
){
86 vec
.PB(make_pair(len
+d3
, i
));
88 vec
.PB(make_pair(d3
-len
, i
));
91 sort(vec
.begin(), vec
.end());
92 reverse(vec
.begin(), vec
.end());
95 while(v
!= M
&& tri
!= ant
){
96 int w
= vec
[v
].second
;
98 if( adentro(w
, ind
, tri
, aux
) ){
99 fijo
[ind
][tri
][aux
] = fijo
[ind
][aux
][tri
] = true;
100 fijo
[tri
][ind
][aux
] = fijo
[tri
][aux
][ind
] = true;
101 fijo
[aux
][ind
][tri
] = fijo
[aux
][tri
][ind
] = true;
102 if( aux
!= ant
&& adentro(w
, ind
, aux
, (aux
+1)%N
) ) tri
= aux
;
107 bool visited
[51][51][51];
108 double b
[51][51][51];
109 double back(int last
, int tamos
, int vamos
){
110 if( tamos
== vamos
) return dist(tow
[last
][0], tow
[last
][1], tow
[tamos
][0], tow
[tamos
][1]);
111 if( visited
[last
][tamos
][vamos
] ) return b
[last
][tamos
][vamos
];
112 visited
[last
][tamos
][vamos
] = true;
113 double & res
= b
[last
][tamos
][vamos
];
114 res
= back(tamos
, (tamos
+1)%N
, vamos
) + dist(tow
[last
][0], tow
[last
][1], tow
[tamos
][0], tow
[tamos
][1]);
115 if(!fijo
[last
][tamos
][(tamos
+1)%N
]){
116 res
= min( res
, back(last
, (tamos
+1)%N
, vamos
));
122 scanf("%i %i", &N
, &M
);
123 for(i
=0;i
<N
;i
++)scanf("%i %i",&tow
[i
][0], &tow
[i
][1]);
124 for(i
=0;i
<M
;i
++)scanf("%i %i",&p
[i
][0], &p
[i
][1]);
125 memset(fijo
, false, sizeof(fijo
));
126 for(i
=0;i
<M
;i
++) for(j
=0;j
<2;j
++) m
[i
][j
] = (double) p
[i
][j
];
127 for(i
=0;i
<N
;i
++) f( i
);
128 double res
= 1000000000000.0;
129 memset(visited
, false, sizeof(visited
));
130 for(i
=0;i
<N
;i
++)for(j
=i
+1;j
<N
;j
++)for(k
=j
+1;k
<N
;k
++){
131 if( cruz3(tow
[i
][0], tow
[i
][1], tow
[j
][0], tow
[j
][1], tow
[k
][0], tow
[k
][1])/ 2.0 < 1e-7 ) continue;
132 double aux
= back(i
, (i
+1)%N
, j
) + back(j
, (j
+1)%N
, k
) + back(k
, (k
+1)%N
, i
);
133 res
= min( res
, aux
);
135 if( res
> 10000000000.0 ) while(1);
136 printf("%.2lf\n", res
);