Advertisement
yicongli

LG4073

Mar 3rd, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.02 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define gc c=getchar()
  6. #define r(x) read(x)
  7. #define ll long long
  8. #define db double
  9.  
  10. template<typename T>
  11. inline void read(T&x){
  12.     x=0;T k=1;char gc;
  13.     while(!isdigit(c)){if(c=='-')k=-1;gc;}
  14.     while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
  15. }
  16.  
  17. const int N=2e5+7;
  18. const db eps=1e-6;
  19.  
  20. struct Point{
  21.     //这里坐标都是原来的两倍
  22.     //这样就可以用int储存了
  23.     int x,y;
  24.    
  25.     Point(){}
  26.     Point(int x,int y):x(x),y(y){}
  27. };
  28.  
  29. #define Vec Point
  30.  
  31. inline Vec operator -(const Vec &a,const Vec &b){
  32.     return Vec(a.x-b.x,a.y-b.y);
  33. }
  34.  
  35. inline ll Cross(const Vec &a,const Vec &b){
  36.     return (ll)a.x*b.y-(ll)a.y*b.x;
  37. }
  38.  
  39. inline db Angle(const Vec &a){
  40.     return atan2(a.y,a.x);
  41. }
  42.  
  43. int n,m,q;
  44.  
  45. namespace Graph{
  46.    
  47.     Point P[N];
  48.    
  49.     struct Edge{
  50.         int u,v,w;
  51.         db angle;
  52.         Edge(){}
  53.         Edge(int u,int v,int w):u(u),v(v),w(w),angle(Angle(P[v]-P[u])){}
  54.     };
  55.    
  56.     int tot,OUT;
  57.     int ecnt=1;
  58.     Edge E[N];
  59.     int ID[N];
  60.     int nex[N];
  61.     vector<int>G[N];
  62.    
  63.     inline void addedge(int u,int v,int w){
  64.         E[++ecnt]=Edge(u,v,w),G[u].push_back(ecnt);
  65.         E[++ecnt]=Edge(v,u,w),G[v].push_back(ecnt);
  66.     }
  67.    
  68.     inline bool cmp(const int &a,const int &b){
  69.         return E[a].angle<E[b].angle;
  70.     }
  71.    
  72.     inline void work(){
  73.         r(n),r(m);
  74.         for(int i=1;i<=n;++i){
  75.             int x,y;r(x),r(y);
  76.             P[i]=Point(x*2,y*2);
  77.         }
  78.         for(int i=1;i<=m;++i){
  79.             int u,v,w;
  80.             r(u),r(v),r(w);
  81.             addedge(u,v,w);
  82.         }
  83.         //极角排序
  84.         //ID表示排名
  85.         for(int i=1;i<=n;++i){
  86.             sort(G[i].begin(),G[i].end(),cmp);
  87.             for(int j=1;j<G[i].size();++j){
  88.                 ID[G[i][j]]=j;
  89.             }
  90.         }
  91.         //nex表示下一条该走哪条
  92.         //就是其反向边的前一条
  93.         for(int i=2;i<=ecnt;++i){
  94.             int x=E[i].v;
  95.             if(ID[i^1])nex[i]=G[x][ID[i^1]-1];
  96.             else nex[i]=G[x][G[x].size()-1];
  97.         }
  98.         //ID现在表示所属区域
  99.         for(int i=2;i<=ecnt;++i)ID[i]=0;
  100.         for(int i=2;i<=ecnt;++i){
  101.             if(!ID[i]){
  102.                 ID[i]=++tot;
  103.                 ll Area=0;
  104.                 for(int j=nex[i];j!=i;j=nex[j]){
  105.                     ID[j]=tot;
  106.                     Area+=Cross(P[E[i].u]-P[E[j].u],P[E[i].u]-P[E[j].v]);
  107.                 }
  108.                 //无穷大区域面积为负
  109.                 if(Area<0)OUT=tot;
  110.             }
  111.         }
  112.     }
  113. }
  114.  
  115. namespace Local{
  116.    
  117.     struct Node{
  118.         int id;
  119.         Point A;
  120.         inline Node(){}
  121.         inline Node(const int &id,const Point &A):id(id),A(A){}
  122.         inline bool operator <(const Node &x)const {
  123.             return (A.x==x.A.x)?id<x.id:A.x<x.A.x;
  124.         }
  125.     };
  126.    
  127.     inline bool cmp(const Node &a,const Node &b){
  128.         return a.id<b.id;
  129.     }
  130.    
  131.     int NOW;
  132.     struct Info{
  133.         int id;
  134.         db k,b;
  135.         int x,y;
  136.         inline Info(){}
  137.         inline Info(const int &id,const Point &A,const Point &B):id(id){
  138.             x=A.x;
  139.             y=A.y;
  140.             k=(db)(A.y-B.y)/(A.x-B.x);
  141.             b=y-k*x;
  142.         }
  143.        
  144.         inline db f()const {
  145.             return k*NOW+b;
  146.         }
  147.         //先按高低排再按斜率排
  148.         inline bool operator < (const Info &A)const {
  149.             db t=f()-A.f();
  150.             if(fabs(t)<eps)return k<A.k;
  151.             return t<0;
  152.         }
  153.     };
  154.    
  155.     Node S[N];
  156.     Node Q[N];
  157.     int Pos[N];
  158.     Info Data[N];
  159.     set<Info>Set;
  160.    
  161.     inline void work(){
  162.         r(q);
  163.         for(int i=0;i<q<<1;++i){
  164.             db x,y;
  165.             scanf("%lf%lf",&x,&y);
  166.             Q[i]=Node(i,Point(x*2,y*2));
  167.         }
  168.         sort(Q,Q+(q<<1));
  169.        
  170.         using Graph::P;
  171.         using Graph::E;
  172.         using Graph::ID;
  173.         using Graph::ecnt;
  174.         int tot=0;
  175.         for(int i=2;i<=ecnt;i+=2){
  176.             if(P[E[i].u].x>P[E[i].v].x)i^=1;
  177.             if(P[E[i].u].x==P[E[i].v].x)continue;
  178.             S[tot++]=Node(i,P[E[i].u]);
  179.             S[tot++]=Node(-i,P[E[i].v]);
  180.         }
  181.         sort(S,S+tot);
  182.        
  183.         for(int i=0,j=0;i<(q<<1);++i){
  184.             while(j<tot&&S[j].A.x<=Q[i].A.x){
  185.                 NOW=S[j].A.x;
  186.                 int id=S[j].id;
  187.                 if(id<0)Set.erase(Data[-id]);
  188.                 else Set.insert(Data[id]=Info(id,P[E[id].u],P[E[id].v]));
  189.                 ++j;
  190.             }
  191.             NOW=Q[i].A.x;
  192.             Point A=Q[i].A;
  193.             Point B=A;B.x++;
  194.             //上面没有边,在无界区域
  195.             if(Set.lower_bound(Info(0,A,B))==Set.end())Pos[Q[i].id]=Graph::OUT;
  196.             else {
  197.                 //上面有边,因为当前边一定是从左到右,所以在其反向边所在区域
  198.                 Info t=*Set.lower_bound(Info(0,A,B));
  199.                 Pos[Q[i].id]=ID[t.id^1];
  200.             }
  201.         }
  202.     }
  203.    
  204. }
  205.  
  206. namespace Tree{
  207.     struct Edge{
  208.         int u,v,w;
  209.        
  210.         inline Edge(){}
  211.         inline Edge(int u,int v,int w):u(u),v(v),w(w){}
  212.        
  213.         inline bool operator <(const Edge &a)const{
  214.             return w<a.w;
  215.         }
  216.     }E[N];
  217.    
  218.     int ecnt;
  219.     int fir[N],nex[N],to[N],w[N];
  220.    
  221.     inline void addedge(int u,int v,int c){
  222.         nex[++ecnt]=fir[u],fir[u]=ecnt,to[ecnt]=v,w[ecnt]=c;
  223.         nex[++ecnt]=fir[v],fir[v]=ecnt,to[ecnt]=u,w[ecnt]=c;
  224.     }
  225.    
  226.     int dep[N];
  227.     int ac[N][20];
  228.     int mx[N][20];
  229.    
  230.     void dfs(int x,int f){
  231.         dep[x]=dep[f]+1;
  232.         ac[x][0]=f;
  233.         for(int i=1;(ac[x][i]=ac[ac[x][i-1]][i-1]);++i){
  234.             mx[x][i]=max(mx[x][i-1],mx[ac[x][i-1]][i-1]);
  235.         }
  236.         for(int i=fir[x];i;i=nex[i]){
  237.             int v=to[i];
  238.             if(v==f)continue;
  239.             mx[v][0]=w[i];
  240.             dfs(v,x);
  241.         }
  242.     }
  243.    
  244.     inline int query(int u,int v){
  245.         int ret=0;
  246.         if(dep[u]<dep[v])swap(u,v);
  247.         for(int i=17;~i;--i){
  248.             if(dep[ac[u][i]]>=dep[v]){
  249.                 ret=max(ret,mx[u][i]);
  250.                 u=ac[u][i];
  251.             }
  252.         }
  253.         if(u==v)return ret;
  254.         for(int i=17;~i;--i){
  255.             if(ac[u][i]!=ac[v][i]){
  256.                 ret=max(ret,mx[u][i]);
  257.                 ret=max(ret,mx[v][i]);
  258.                 u=ac[u][i],v=ac[v][i];
  259.             }
  260.         }
  261.         return max(ret,max(mx[u][0],mx[v][0]));
  262.     }
  263.  
  264.     int fa[N];
  265.    
  266.     int find(int x){
  267.         return x==fa[x]?x:fa[x]=find(fa[x]);
  268.     }
  269.    
  270.     inline bool uni(int u,int v){
  271.         u=find(u),v=find(v);
  272.         if(u==v)return 0;
  273.         fa[u]=v;
  274.         return 1;
  275.     }
  276.     //注意特判无解
  277.     inline void solve(){
  278.         using Graph::ID;
  279.         int tot=0;
  280.         for(int i=2;i<=Graph::ecnt;i+=2){
  281.             E[++tot]=Edge(ID[i],ID[i^1],Graph::E[i].w);
  282.         }
  283.         sort(E+1,E+tot+1);
  284.         for(int i=1;i<=Graph::tot;++i)fa[i]=i;
  285.         for(int i=1;i<=tot;++i){
  286.             if(E[i].u==Graph::OUT||E[i].v==Graph::OUT)continue;
  287.             if(uni(E[i].u,E[i].v)){
  288.                 addedge(E[i].u,E[i].v,E[i].w);
  289.                 if(ecnt==(n-1)*2)break;
  290.             }
  291.         }
  292.         for(int i=1;i<=Graph::tot;++i){
  293.             if(!ac[i][0])dfs(i,0);
  294.         }
  295.         using Local::Pos;
  296.         for(int i=0;i<(q<<1);i+=2){
  297.             if(find(Pos[i])!=find(Pos[i^1])||Pos[i]==Graph::OUT)puts("-1");
  298.             else printf("%d\n",query(Pos[i],Pos[i^1]));
  299.         }
  300.     }
  301. }
  302.  
  303. int main(){
  304.     Graph::work();
  305.     Local::work();
  306.     Tree::solve();
  307.     return 0;
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement