gym 101657 D

时间:2024-01-12 21:17:38

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

傻逼题。

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

 #include <bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
typedef double db;
const int N = 1e6+;
const db eps = 1e-;
const db pi = acos(-);
int sign(db k){
if (k>eps) return ; else if (k<-eps) return -; return ;
}
int cmp(db k1,db k2){return sign(k1-k2);}
struct point{
db x,y;
point operator+(const point &k1)const { return point{k1.x+x,k1.y+y};}
point operator-(const point &k1)const { return point{x-k1.x,y-k1.y};}
point operator*(const db k1)const { return point{x*k1,y*k1};}
point operator / (db k1) const{return (point){x/k1,y/k1};}
db abs(){return sqrt(x*x+y*y);}
bool operator<(const point k1)const {
int a = cmp(x,k1.x);
if (a==-) return ; else if (a==) return ; else return cmp(y,k1.y)==-;
}
bool operator== (const point k1)const {
return x==k1.x&&y==k1.y;
}
};
db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
struct line{
point p[];//x小的是p[0]
line(point k1,point k2){
if(k1<k2)
p[]=k1,p[]=k2;
else
p[]=k2,p[]=k1;
}
point &operator[](int k){ return p[k];}
bool operator <(const line &k1)const {
if(p[]==k1.p[])
return p[]<k1.p[];
return p[]<k1.p[];
}
};
struct Tri{
point p[],o;
point &operator[](int k){ return p[k];}
}tri[N];
map<line,int> mp;
vector<line> L;
int cnt = ;
vector<int> g[N*],f[N];
int deg[N];
int t,n;
int main(){
//freopen("awsl.in","r",stdin);
scanf("%d",&t);
while (t--){
scanf("%d",&n);
for(int i=;i<n;i++){
tri[i].o.x=,tri[i].o.y=;
for(int j=;j<;j++){
scanf("%lf%lf",&tri[i][j].x,&tri[i][j].y);
tri[i].o.x+=tri[i][j].x;
tri[i].o.y+=tri[i][j].y;
}
tri[i].o.x/=,tri[i].o.y/=;
for(int j=;j<;j++){
line tmp = line(tri[i][j],tri[i][(j+)%]);
if(mp.count(tmp)){
g[mp[tmp]].push_back(i);
} else{
mp[tmp]=cnt;
L.push_back(tmp);
g[cnt].push_back(i);
cnt++;
}
}
}
for(int i=;i<cnt;i++){
if(g[i].size()<)continue;
int s1 = g[i][],s2 = g[i][];
line tmp = L[i];
db t = cross(tmp[]-tmp[],tri[s1].o-tmp[]);
if(sign(t)>){//s1在上面
f[s1].push_back(s2);
deg[s2]++;
} else{
f[s2].push_back(s1);
deg[s1]++;
}
}
queue<int> q;
for(int i=;i<n;i++){
if(deg[i]==)
q.push(i);
}
vector<int> ans;
while (!q.empty()){
int t = q.front();
q.pop();
ans.push_back(t+);
for(int i=;i<f[t].size();i++){
deg[f[t][i]]--;
if(deg[f[t][i]]==)
q.push(f[t][i]);
}
}
reverse(ans.begin(),ans.end());
for(auto tmp:ans){
printf("%d ",tmp);
}
printf("\n");
for(int i=;i<n;i++){
deg[i]=;
f[i].clear();
}
for(int i=;i<cnt;i++)
g[i].clear();
L.clear();mp.clear();
cnt=;
}
}