poj 1151 hdu 1542 Atlantis 線段樹掃描線,詳細講解,(*^__^*) 嘻嘻……
阿新 • • 發佈:2019-01-28
我的掃面線第一題,一開始看網上講的都好抽象,最後還是研究別人程式碼整明白的,所以我要寫一個直觀的,哈哈哈!!希望大家都能看懂
如圖虛線將整個圖型分成三個矩形,我們現將每個點的x進行排序,也就是(10,15,20,25.5)
這樣就知道矩形的長了,還差寬,然後我們就要開始掃描線啦
先每個點的y值離散話,因為我們要求的是對映在x軸的線段,然後建樹,共有t哥點,樣立t-1等於4
下面的線段樹我每個離散花後的點對應的y值我都標記上了
將一號邊加入線段,先加入一號邊,二號邊三號邊四號邊具體過程建議自己模擬一下
我每個線段樹的點用s標記這條邊被覆蓋還是沒被都蓋,每條邊的flag表示這天邊是入度還是出度
注意啊!!我這個圖x,y軸畫反啦
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define N 300 struct Node{ double x;double y1;double y2; int flag; }node[N]; bool cmp(Node a,Node b){ return a.x-b.x<0.0000001; } double y[N]; struct node{ int l;int r;double ml;double mr;int s;double len; }a[N*3]; void build(int i,int left,int right){ a[i].l=left; a[i].r=right; a[i].ml=y[left]; a[i].mr=y[right]; a[i].s=0; a[i].len=0; if(a[i].l+1==a[i].r){ return ; } int mid=(left+right)>>1; build(i*2,left,mid); build(i*2+1,mid,right);//建樹時注意這裡不是mid+1,因為做相減的時候如果mid+1這麼建回到值左孩子的右邊與有孩子的左邊無法進行運算 } void callen(int i){ if(a[i].s>0){//注意這裡不是所有邊都是左孩子的長度加上右孩子的長度,他存在一個覆蓋問題 a[i].len=a[i].mr-a[i].ml; }else if(a[i].r-a[i].l==1){ a[i].len=0; }else{ a[i].len=a[i*2].len+a[i*2+1].len; } return ; } void updata(int i,Node b){ if(a[i].ml==b.y1&&a[i].mr==b.y2){ a[i].s+=b.flag; callen(i); return ; } if(b.y2<=a[i*2].mr) updata(i*2,b); else if(b.y1>=a[i*2+1].ml) updata(i*2+1,b); else{ Node temp=b; temp.y2=a[i*2].mr; updata(i*2,temp); temp=b; temp.y1=a[i*2+1].ml; updata(i*2+1,temp); } callen(i); return ; } int main(){ // freopen("in.txt","r",stdin); int n,t,p=1,te; double x1,x2,y1,y2; while(scanf("%d",&n),n){ t=1; for(int i=0;i<n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); node[t].x=x1; node[t].y1=y1; node[t].y2=y2; node[t].flag=1;//入邊 y[t++]=y1; node[t].x=x2; node[t].y1=y1; node[t].y2=y2; node[t].flag=-1;//出邊 y[t++]=y2; } sort(node+1,node+t,cmp); sort(y+1,y+t); build(1,1,t-1); updata(1,node[1]); double sum=0; for(int i=2;i<t;i++){ sum+=a[1].len*(node[i].x-node[i-1].x); updata(1,node[i]); } printf("Test case #%d\n",p++); printf("Total explored area: %.2lf\n\n",sum); } return 0; }