gym 101657 D

理论1A。  //没删debug的文件读入。。

傻逼题。

先求出来每条边两侧的三角形,然后枚举边,根据叉积判断三角形位置,建图,拓扑排序。

  1 #include <bits/stdc++.h>
  2 #define pii pair<int,int>
  3 using namespace std;
  4 typedef double db;
  5 const int N = 1e6+6;
  6 const db eps = 1e-6;
  7 const db pi = acos(-1);
  8 int sign(db k){
  9     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
 10 }
 11 int cmp(db k1,db k2){return sign(k1-k2);}
 12 struct point{
 13     db x,y;
 14     point operator+(const point &k1)const { return point{k1.x+x,k1.y+y};}
 15     point operator-(const point &k1)const { return point{x-k1.x,y-k1.y};}
 16     point operator*(const db k1)const { return point{x*k1,y*k1};}
 17     point operator / (db k1) const{return (point){x/k1,y/k1};}
 18     db abs(){return sqrt(x*x+y*y);}
 19     bool operator<(const point k1)const {
 20         int a = cmp(x,k1.x);
 21         if (a==-1) return 1; else if (a==1) return 0; else return cmp(y,k1.y)==-1;
 22     }
 23     bool operator== (const point k1)const {
 24         return x==k1.x&&y==k1.y;
 25     }
 26 };
 27 db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
 28 db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
 29 struct line{
 30     point p[2];//x小的是p[0]
 31     line(point k1,point k2){
 32         if(k1<k2)
 33             p[0]=k1,p[1]=k2;
 34         else
 35             p[0]=k2,p[1]=k1;
 36     }
 37     point &operator[](int k){ return p[k];}
 38     bool operator <(const line &k1)const {
 39         if(p[0]==k1.p[0])
 40             return p[1]<k1.p[1];
 41         return p[0]<k1.p[0];
 42     }
 43 };
 44 struct Tri{
 45     point p[3],o;
 46     point &operator[](int k){ return p[k];}
 47 }tri[N];
 48 map<line,int> mp;
 49 vector<line> L;
 50 int cnt = 0;
 51 vector<int> g[N*3],f[N];
 52 int deg[N];
 53 int t,n;
 54 int main(){
 55     //freopen("awsl.in","r",stdin);
 56     scanf("%d",&t);
 57     while (t--){
 58         scanf("%d",&n);
 59         for(int i=0;i<n;i++){
 60             tri[i].o.x=0,tri[i].o.y=0;
 61             for(int j=0;j<3;j++){
 62                 scanf("%lf%lf",&tri[i][j].x,&tri[i][j].y);
 63                 tri[i].o.x+=tri[i][j].x;
 64                 tri[i].o.y+=tri[i][j].y;
 65             }
 66             tri[i].o.x/=3,tri[i].o.y/=3;
 67             for(int j=0;j<3;j++){
 68                 line tmp = line(tri[i][j],tri[i][(j+1)%3]);
 69                 if(mp.count(tmp)){
 70                     g[mp[tmp]].push_back(i);
 71                 } else{
 72                     mp[tmp]=cnt;
 73                     L.push_back(tmp);
 74                     g[cnt].push_back(i);
 75                     cnt++;
 76                 }
 77             }
 78         }
 79         for(int i=0;i<cnt;i++){
 80             if(g[i].size()<2)continue;
 81             int s1 = g[i][0],s2 = g[i][1];
 82             line tmp = L[i];
 83             db t = cross(tmp[1]-tmp[0],tri[s1].o-tmp[0]);
 84             if(sign(t)>0){//s1在上面
 85                 f[s1].push_back(s2);
 86                 deg[s2]++;
 87             } else{
 88                 f[s2].push_back(s1);
 89                 deg[s1]++;
 90             }
 91         }
 92         queue<int> q;
 93         for(int i=0;i<n;i++){
 94             if(deg[i]==0)
 95                 q.push(i);
 96         }
 97         vector<int> ans;
 98         while (!q.empty()){
 99             int t = q.front();
100             q.pop();
101             ans.push_back(t+1);
102             for(int i=0;i<f[t].size();i++){
103                 deg[f[t][i]]--;
104                 if(deg[f[t][i]]==0)
105                     q.push(f[t][i]);
106             }
107         }
108         reverse(ans.begin(),ans.end());
109         for(auto tmp:ans){
110             printf("%d ",tmp);
111         }
112         printf("\n");
113         for(int i=0;i<n;i++){
114             deg[i]=0;
115             f[i].clear();
116         }
117         for(int i=0;i<cnt;i++)
118             g[i].clear();
119         L.clear();mp.clear();
120         cnt=0;
121     }
122 }
View Code

 

posted @ 2019-03-04 12:09  MXang  阅读(141)  评论(0编辑  收藏  举报