【模板】【凸包】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

 

你可能感兴趣的:(模板)