萌新求助简单平面图+微量计算几何
查看原帖
萌新求助简单平面图+微量计算几何
455490
Sharpsmile楼主2024/9/11 18:41

WA 在了 #9 上,但是不知道为啥。qwq

求大佬帮帮。

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define pii pair<int ,int>
#define p1(x) x.first
#define p2(x) x.second
#define int long long 
#define ll long long 

int n,m,k;
struct node{
    int x,y;
    friend ll operator *(const node A,const node B){
        return 1ll*A.x*B.y-1ll*A.y*B.x;
    } 
    friend node operator+(const node A,const node B){
        return {A.x+B.x,A.y+B.y};
    }
    friend node operator-(const node A,const node B){
        return {A.x-B.x,A.y-B.y};
    }
    friend bool operator ==(const node A,const node B){
        return A.x==B.x&&A.y==B.y;
    }
    inline double ang(){
        return atan2(y,x);
    }
}A[100300];
int u[200300],v[200300],w[200300];
ll ar[200300];
int pre[200300];
vector<int>g[200300],P[200300];
vector<pii>G[200300];
inline bool cmpa(int x,int y){
    return (A[v[x]]-A[u[x]]).ang()<(A[v[y]]-A[u[y]]).ang();
}
bool vis[200300];
int s;
int bel[200300];
bool abl[200300];
struct edge{int u,v,w;};
vector<edge>E;
int f[400300];
int lc[400300],rc[400300],wt[400300];
inline int ff(int x){return f[x]==x?x:f[x]=ff(f[x]);}
inline void merge(int x,int y,int w){
    x=ff(x),y=ff(y);
    if(x==y)return ;
    ++s;
    lc[s]=x,rc[s]=y;
    wt[s]=w;
    f[x]=f[y]=s;
}
inline bool cmpe(edge A,edge B){return A.w<B.w;}
inline void KR(){
    for(int i=1;i<=2*s;i++)
        f[i]=i;
    sort(E.begin(),E.end(),cmpe);
    for(edge e:E)
    merge(e.u,e.v,e.w);
}
int dep[400300];
int fa[400030][20];
inline void dfs(int x){
    dep[x]=dep[fa[x][0]]+1;
    for(int i=1;i<=18;i++) 
        fa[x][i]=fa[fa[x][i-1]][i-1];
    if(lc[x])fa[lc[x]][0]=x,dfs(lc[x]);
    if(lc[x])fa[rc[x]][0]=x,dfs(rc[x]);
}
inline int MN(int u,int v){
    if(!u||!v||ff(u)!=ff(v))return -1;

    if(dep[u]<dep[v])swap(u,v);
    int L=18;
    while(dep[u]>dep[v]){
        if(dep[fa[u][L]]>=dep[v])u=fa[u][L];
        L--;
    }
    // cout<<u<<" "<<v<<" x"<<endl;;
    if(u==v)return wt[v];
    L=18;
    while(L>=0){
        if(fa[u][L]!=fa[v][L])
            u=fa[u][L],v=fa[v][L];
        L--;
    }
    return wt[fa[u][0]];
}
struct ask{int x,y,id;}ASK[200300];
int TO[200300];
struct line {
    node A,B;
    int id;
    friend bool operator<(const line P,const line Q){
        if(P.A.x==Q.A.x){
            if(P.A.y==Q.A.y)return P.B.y>Q.B.y;
            else return P.A.y>Q.A.y;
        }
        else if(P.A.x<Q.A.x)
        return (Q.A-P.A)*(P.B-P.A)>0;
        else return (Q.B-Q.A)*(P.A-Q.A)>0;
    }
    friend bool operator==(const line P,const line Q){
        return P.A==Q.A&&P.B==Q.B&&P.id==Q.id;
    }
};
set<line>S;
vector<line>I,D;
inline bool cmpx(ask P,ask Q){
    return P.x<Q.x;
}
inline bool cmpi(line P,line Q){
    return P.A.x<Q.A.x;
}
inline bool cmpd(line P,line Q){
    return P.B.x<Q.B.x;
}
inline void prt(line P){
    cout<<P.A.x<<" "<<P.A.y<<" "<<P.B.x<<" "<<P.B.y<<" "<<P.id<<endl;
}
signed main(){
    // freopen("genshin.in","r",stdin);
    // freopen("genshin.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int id=1;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>A[i].x>>A[i].y,A[i].x*=2,A[i].y*=2;
    for(int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        if(A[a].x>A[b].x)swap(a,b);
        u[++id]=a,v[id]=b;
        w[id]=c;
        g[a].push_back(id);
        swap(a,b);
        u[++id]=a,v[id]=b,w[id]=c;
        g[a].push_back(id);

    }
    for(int i=1;i<=n;i++){
        sort(g[i].begin(),g[i].end(),cmpa);
        pre[g[i][0]]=g[i].back();
        int k=g[i].size();
        for(int j=1;j<k;j++)
            pre[g[i][j]]=g[i][j-1];
    }
    int rt=0;
    for(int i=2;i<=id;i++)
    if(!vis[i]){
        int x=i;
        ++s;
        while(!vis[i]){
            vis[i]=1;
            bel[i]=s;
            // cout<<A[u[i]].x<<" "<<A[u[i]].y<<" "<<A[v[i]].x<<" "<<A[v[i]].y<<" "<<s<<endl;
            P[s].push_back(v[i]);
            i=pre[i^1];
        }
        int k=P[s].size();
        for(int i=2;i<k;i++)
        ar[s]+=(A[P[s][i-1]]-A[P[s][0]])*(A[P[s][i]]-A[P[s][0]]);
        if(ar[s]>0)abl[s]=1;
    }
    for(int i=2;i<=2*m+1;i++)
        if(!abl[bel[i]])bel[i]=0;
    for(int i=2;i<=2*m;i+=2)
    if(abl[bel[i]]&&abl[bel[i+1]])
        E.push_back({bel[i],bel[i+1],w[i]});
    
    KR();
    // return 0;
    for(int i=1;i<=s;i++)
        if(!dep[i])dfs(ff(i));
    for(int i=2;i<=2*m;i+=2)
    if(A[u[i]].x!=A[v[i]].x)
    I.push_back({A[u[i]],A[v[i]],bel[i]}),
    D.push_back({A[u[i]],A[v[i]],bel[i]});

    cin>>k;
    for(int i=1;i<=k;i++){
        double a,b,c,d;
        cin>>a>>b>>c>>d;
        a*=2,b*=2,c*=2,d*=2;
        ASK[i]={(int)a,(int)b,i};
        ASK[i+k]={(int)c,(int)d,i+k};       
    }
    sort(ASK+1,ASK+2*k+1,cmpx);
    sort(I.begin(),I.end(),cmpi);
    sort(D.begin(),D.end(),cmpd);
    S.insert({{(int)-1e9,(int)-1e9},{(int)1e9,(int)-1e9},0});
    auto iti=I.begin(),itd=D.begin();
    for(int i=1;i<=2*k;i++){
        while((iti!=I.end()&&(*iti).A.x<ASK[i].x)||(itd!=D.end()&&(*itd).B.x<ASK[i].x)){
            bool a=iti!=I.end()&&(*iti).A.x<ASK[i].x;
            bool b=itd!=D.end()&&(*itd).B.x<ASK[i].x;
            // cout<<endl;
            // for(line L:S)
            // cout<<L.A.x<<"x"<<L.A.y<<" "<<L.B.x<<"x"<<L.B.y<<" "<<L.id<<endl;
            if(!b)//cout<<"I1 ",prt(*iti),
                S.insert(*iti),iti++,a=1;
            else if(!a) //cout<<"D1 ",prt(*itd),
                S.erase(*itd),itd++,b=1;
            else if((*itd).B.x<=(*iti).A.x)//cout<<"D2 ",prt(*itd),
                S.erase(*itd),itd++,a=0;
            else //cout<<"I2 ",prt(*iti),
                S.insert(*iti),iti++,b=0;

            // for(line L:S)
            // cout<<L.A.x<<"x"<<L.A.y<<" "<<L.B.x<<"x"<<L.B.y<<" "<<L.id<<endl;
            // cout<<endl;
        }
        
        TO[ASK[i].id]=(*S.lower_bound({{ASK[i].x,ASK[i].y},{ASK[i].x,ASK[i].y},0})).id;
        
        // cout<<ASK[i].x<<" "<<ASK[i].y<<" "<<ASK[i].id<<" "<<TO[ASK[i].id]<<endl;
    }
    // for(int i=1;i<=2*k;i++)
    // cout<<i<<" "<<TO[i]<<endl;
    for(int i=1;i<=k;i++){
        int u=TO[i],v=TO[i+k];
        cout<<MN(u,v)<<endl;
    }
    return 0;
}
2024/9/11 18:41
加载中...