您的位置:首页 > 其它

POJ 1436 Horizontally Visible Segments(线段树)

2012-08-24 17:17 375 查看
转载请注明出处,谢谢/article/2566293.html
by---cxlove

题目:给出一些垂直的线段,两两可见的三条线段有多少组。

可见是说找出一条水平线段连接两条线段,而且这条线段不和别的线段相交。

http://poj.org/problem?id=1436

被yobobobo问起,竟然线段树没有做

将所有线段按X坐标排序,依次将线段插入

在插入之前先做一次查询,看线段所在的区间中有哪些线段可见。

典型的区间染色问题。

由于这里是线段,区间的端点是包括的,所以要把区间乘以2

相当于线段树中的(2*i,2*i)表示的是i这个点,而(2*i+1,2*i+1)表示的是(i,i+1)这个开区间

打一个邻接表,然后4层循环暴力

#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<ctime>
#include<sstream>
#include<cassert>
#define LL long long
#define eps 1e-7
#define zero(a) fabs(a)<eps
#define inf 1<<30
#define N 8005
#define pi acos(-1.0)
#define pb(a) push_back(a)
#define lson step<<1
#define rson step<<1|1
using namespace std;
struct SegmentTree{
    int left,right,mid;
    int col;
}L[N*2*4];
struct Node{
    int x,y1,y2;
}a[8005];
vector<int>v[8005];
bool cmp(Node n1,Node n2){
    return n1.x<n2.x;
}
void Push_Down(int step){
    if(L[step].col!=-1){
        L[lson].col=L[rson].col=L[step].col;
        L[step].col=-1;
    }
}
void Bulid(int step,int l,int r){
    L[step].left=l;
    L[step].right=r;
    L[step].mid=(l+r)/2;
    L[step].col=0;
    if(l==r) return;
    Bulid(lson,l,L[step].mid);
    Bulid(rson,L[step].mid+1,r);
}
void Update(int step,int l,int r,int c){
    if(l==L[step].left&&r==L[step].right){
        L[step].col=c;
        return;
    }
    Push_Down(step);
    if(r<=L[step].mid) Update(lson,l,r,c);
    else if(l>L[step].mid) Update(rson,l,r,c);
    else{Update(lson,l,L[step].mid,c);Update(rson,L[step].mid+1,r,c);}
}
bool flag[8005];
void Query(int step,int l,int r,int c){
    if(L[step].col!=-1){
        if(L[step].col&&!flag[L[step].col]) v[c].pb(L[step].col);
        flag[L[step].col]=true;
        return ;
    }
    Push_Down(step);
    if(r<=L[step].mid) Query(lson,l,r,c);
    else if(l>L[step].mid) Query(rson,l,r,c);
    else{Query(lson,l,L[step].mid,c);Query(rson,L[step].mid+1,r,c);}
}
int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        int m=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            v[i].clear();
            scanf("%d%d%d",&a[i].y1,&a[i].y2,&a[i].x);
            m=max(m,a[i].y2);
        }
        sort(a+1,a+1+n,cmp);
        Bulid(1,0,2*m);
        for(int i=1;i<=n;i++){
            memset(flag,false,sizeof(flag));
            Query(1,2*a[i].y1,2*a[i].y2,i);
            Update(1,2*a[i].y1,2*a[i].y2,i);
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<v[i].size();j++){
                for(int k=0;k<v[v[i][j]].size();k++)
                    for(int r=0;r<v[i].size();r++)
                        if(v[i][r]==v[v[i][j]][k]) ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: