計蒜客 回收元件 拓撲排序(Java版)
阿新 • • 發佈:2018-12-20
題目大意:將各個元件按照某個次序向y軸負半軸移動,直到所有元件全部移出工作區,我的想法是如果a元件的左端點橫座標在b元件兩個端點的橫座標中間時,判斷a元件左端點的縱座標ya與a元件左端點橫座標在b元件上的縱座標位置yb,如果ya大於yb,說明要先移動b元件,所以我們可以建圖點b指向a,a點的入度增加,n^2遍歷所有的元件之後可以得到一個圖,然後進行拓撲排序輸出即可。 ac程式碼:
import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { static class edge { int x1,y1,x2,y2; edge(int a,int b,int c,int d){ x1=a; y1=b; x2=c; y2=d; } } static class bian{//用來存邊的鄰接表 int v,next; bian(int v,int next){ this.v=v; this.next=next; } } static int p[]=new int[6005]; static bian b[]=new bian[5000000];//剛開始開200萬發現不夠 static int eid=0; static void insert(int u,int v){ b[eid]=new bian(v,p[u]); p[u]=eid++; } static edge e[]=new edge[6005]; static int rudu[]=new int[6005];//儲存元件的入度 public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(); Arrays.fill(p, -1); for(int i=1;i<=n;i++){ int a=sc.nextInt(); int b=sc.nextInt(); int c=sc.nextInt(); int d=sc.nextInt(); if(a>c){ int temp=a; a=c; c=temp; temp=b; b=d; d=temp; } e[i]=new edge(a,b,c,d); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j&&e[i].x1>=e[j].x1&&e[i].x1<=e[j].x2){ double y; if(e[j].x1==e[j].x2) y=(e[j].y1+e[j].y2)/2.0; else y=1.0*(e[i].x1-e[j].x1)*(e[j].y2-e[j].y1)/(e[j].x2-e[j].x1)+e[j].y1; if(y>e[i].y1){ //比較兩個y的大小來判斷優先度 rudu[j]++; insert(i,j); }else{ rudu[i]++; insert(j,i); } } } } Queue<Integer> q=new LinkedList<Integer>(); for(int i=1;i<=n;i++) //拓撲排序,初始入度為0的點入佇列 if(rudu[i]==0) q.add(i); while(!q.isEmpty()){ int u=q.poll(); for(int i=p[u];i!=-1;i=b[i].next){ int v=b[i].v; if(--rudu[v]==0) q.add(v); } if(!q.isEmpty()) System.out.print(u+" "); else System.out.println(u); } sc.close(); } }