【模板】【凸包】Graham_scan
1 /* 2 唐代李白 3 《江夏别宋之悌》 4 楚水清若空,遥将碧海通。人分千里外,兴在一杯中。 5 谷鸟吟晴日,江猿啸晚风。平生不下泪,于此泣无穷. 6 */ 7 #include <iostream> 8 #include <cstdio> 9 #include <algorithm> 10 #include <cstring> 11 #include <vector> 12 #include <utility> 13 #include <iomanip> 14 #include <string> 15 #include <cmath> 16 #include <queue> 17 #include <assert.h> 18 #include <map> 19 #include <ctime> 20 #include <cstdlib> 21 #include <stack> 22 #include <set> 23 #define LOCAL 24 const int INF = 0x7fffffff; 25 const int MAXN = 100000 + 10; 26 const int maxnode = 20000 * 2 + 200000 * 20; 27 const int MAXM = 50000 + 10; 28 const int MAX = 100; 29 using namespace std; 30 struct point{//也是vector 31 int x, y; 32 }p[MAXN], stack[MAXN]; 33 int top; 34 int dis(point p1,point p2){return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);} 35 //叉积,结果小于表示向量p0p1的极角大于p0p2的极角,等于则0两向量共线 36 int multi(point p1, point p2, point p0){//p0为坐标 37 return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); 38 } 39 40 int cmp(point a,point b){ 41 if(multi(a,b,p[0]) > 0) return 1; 42 if(multi(a,b,p[0]) == 0 && dis(a,p[0]) < dis(b,p[0])) return 1; 43 return 0; 44 } 45 //Graham_scan凸包扫描 46 void Graham_scan(point p[],point stack[],int n){ 47 int i, j, k = 0; 48 top=2; 49 point temp; 50 51 for(i=1;i<n;i++) if(p[i].y<p[k].y||((p[i].y==p[k].y)&&(p[i].x<p[k].x))) k=i; 52 swap(p[0], p[k]); 53 //按极角从小到大,距离偏短进行排序 54 sort(p + 1, p + n, cmp); 55 stack[0] = p[0]; 56 stack[1] = p[1]; 57 stack[2] = p[2]; 58 for (int i = 3; i < n; i++){ 59 while(top > 1 && multi(p[i],stack[top],stack[top-1]) >= 0) 60 top--; 61 stack[++top] = p[i]; 62 } 63 } 64 65 int main(){ 66 #ifdef LOCAL 67 freopen("data.txt", "r", stdin); 68 freopen("out.txt", "w", stdout); 69 #endif 70 //printf("%d", (a == c)); 71 return 0; 72 }