暑假集训-数据结构

求矩形的并 Poj1151

线段树,离散化,扫描线。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <fstream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <deque>
  7 #include <vector>
  8 #include <queue>
  9 #include <string>
 10 #include <cstring>
 11 #include <map>
 12 #include <stack>
 13 #include <set>
 14 #define LL long long
 15 #define INF 0x3f3f3f3f
 16 #define OPEN_FILE
 17 using namespace std;
 18 const int MAXN = 5005;
 19 struct Line{
 20     double left, right;
 21     double y;
 22     int cnt;
 23     Line(){};
 24     Line(double left, double right, double y, int cnt) :left(left), right(right), y(y), cnt(cnt){};
 25 };
 26 bool operator < (Line a, Line b){
 27     return a.y < b.y;
 28 }
 29 struct Node{
 30     double left, right;
 31     int from, to;
 32     int cnt;
 33     double value;
 34 };
 35 int n;
 36 double a[MAXN];
 37 Line scan[MAXN];
 38 Node f[MAXN << 1];
 39 void build(int t, int left, int right){
 40     f[t].left = a[left];
 41     f[t].right = a[right];
 42     f[t].from = left;
 43     f[t].to = right;
 44     f[t].cnt = f[t].value = 0;
 45     if (right - left == 1) return;
 46     int mid = (left + right) >> 1;
 47     build(t << 1, left, mid);
 48     build((t << 1) + 1, mid, right);
 49 }
 50 void update(int t, Line p){
 51     if (p.left == f[t].left && p.right == f[t].right){
 52         f[t].cnt += p.cnt;
 53         if (f[t].cnt > 0){
 54             f[t].value = p.right - p.left;
 55             return;
 56         }
 57         if (f[t].to - f[t].from == 1){
 58             f[t].value = 0;
 59         }
 60         else{
 61             f[t].value = f[t << 1].value + f[(t << 1) + 1].value;
 62         }
 63         return;
 64     }
 65     if (p.left >= f[(t << 1) + 1].left){
 66         update((t << 1) + 1, p);
 67     }
 68     else if (p.right <= f[t << 1].right){
 69         update(t << 1, p);
 70     }
 71     else{
 72         Line q = p;
 73         q.right = f[t << 1].right;
 74         update(t << 1, q);
 75         q = p;
 76         q.left = f[(t << 1) + 1].left;
 77         update((t << 1) + 1, q);
 78     }
 79     if (f[t].cnt > 0){
 80         f[t].value = f[t].right - f[t].left;
 81     }
 82     else{
 83         f[t].value = f[t].to - f[t].from == 1 ?0:f[t << 1].value + f[(t << 1) + 1].value;
 84     }
 85 }
 86 int main()
 87 {
 88 #ifdef OPEN_FILE
 89     //freopen("in.txt", "r", stdin);
 90     //freopen("out.txt", "w", stdout);
 91 #endif // OPEN_FILE
 92     double x1, y1, x2, y2;
 93     int cas = 1;
 94     while (~scanf("%d", &n) && n != 0){
 95         for (int i = 1; i <= n; i++){
 96             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
 97             a[i * 2 - 1] = x1;
 98             a[i * 2] = x2;
 99             scan[i * 2 - 1] = Line(x1, x2, y1, 1);
100             scan[i * 2] = Line(x1, x2, y2, -1);
101         }
102         n = n * 2;
103         double ans = 0.0;
104         memset(f, 0, sizeof(f));
105         sort(a + 1, a + n + 1);
106         sort(scan + 1, scan + n + 1);
107         build(1, 1, n);
108         update(1, scan[1]);
109         for (int i = 2; i <= n; i++){
110             ans += f[1].value * (scan[i].y - scan[i - 1].y);
111             update(1, scan[i]);
112         }
113         printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas++, ans);
114     }
115 }
View Code

并查集应用 poj1182

以前对并查集的印象还停留在高中,只是记录一下是不是已经连通。这里加了一个数组rank[i]表示i的秩,也就是到祖先的距离,其实都是高中的内容。

//set
void MakeSet(int x){
    father[x] = x;
    rank[x] = 0;
}
//find
int FindSet(int x)
{
    if (x != father[x])
    {
        father[x] = FindSet(father[x]);
    }
    return father[x];
}
//union
void Union(int x, int y)
{
    x = FindSet(x);
    y = FindSet(y);
    if (x == y) return;
    if (rank[x] > rank[y])
    {
        father[y] = x;
        rank[x] += rank[y];
    }
    else
    {
        if (rank[x] == rank[y])
        {
            rank[y]++;
        }
        father[x] = y;
    }
}

 

posted on 2015-07-20 16:01  张济  阅读(160)  评论(0编辑  收藏  举报

导航