【模板】【凸包】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 }
View Code
原文地址:https://www.cnblogs.com/hoskey/p/4347859.html