• BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦


    Description

    给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. (n leqslant 4 imes 10^4) .

    Sol

    加权并查集.

    像向量合成一样合并就可以了,找 (f[x]) 的时候需要先记录现在的父节点,然后更新他新的父节点.

    Code

    /**************************************************************
        Problem: 3362
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:80 ms
        Memory:3712 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
     
    typedef pair< int,int > pr;
    #define abs(x) ((x)<0 ? -(x) : (x) )
    #define mpr make_pair
    #define debug(a) cout<<#a<<"="<<a<<" "
    const int N = 40005;
     
    int n,m,k;
    int f[N],ans[N];pr g[N];
    struct Q{ int a,b,c,d; }q[N],qq[N];
     
    inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x ;}
    inline char read(char ch=getchar()){ while(ch>'Z' || ch<'A') ch=getchar();return ch; }
    pr operator + (const pr &a,const pr &b){ return mpr(a.first+b.first,a.second+b.second); }
    pr operator += (pr &a,const pr &b){ return a=a+b; }
    pr operator - (const pr &a,const pr &b){ return mpr(a.first-b.first,a.second-b.second); }
    pr operator -= (pr &a,const pr &b){ return a=a-b; } 
    int cmp1(const Q &x,const Q &y){ return x.c<y.c; }
    int cmp2(const Q &x,const Q &y){ return x.d<y.d; }
    int find(int x){
        if(f[x] == x) return x;
        int t=f[x];f[x]=find(f[x]);
        g[x]+=g[t];return f[x];
    }
    void work(int u,int v,int w,char d){
        int r1=find(u),r2=find(v);
    //  debug(r1),debug(r2)<<endl;
    //  cout<<u<<" "<<v<<" "<<w<<" "<<d<<endl;
    //  cout<<"qwq"<<endl;
        if(r1!=r2) switch(d){
            case 'N':f[r1]=r2,g[r1]=g[v]+mpr(0,w)-g[u];break;
            case 'W':f[r1]=r2,g[r1]=g[v]+mpr(-w,0)-g[u];break;
            case 'S':f[r1]=r2,g[r1]=g[v]+mpr(0,-w)-g[u];break;
            default:f[r1]=r2,g[r1]=g[v]+mpr(w,0)-g[u];break;
        }
    //  for(int i=1;i<=n;i++) cout<<find(i)<<":("<<g[i].first<<","<<g[i].second<<") ";cout<<endl;
    }
    int main(){
    //  freopen("in.in","r",stdin);
        n=in(),m=in();
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=1;i<=m;i++) qq[i].a=in(),qq[i].b=in(),qq[i].c=in(),qq[i].d=read();
        k=in();for(int i=1;i<=k;i++) q[i].a=in(),q[i].b=in(),q[i].c=in(),q[i].d=i;
        sort(q+1,q+k+1,cmp1);
    //  for(int i=1;i<=m;i++) work(qq[i].a,qq[i].b,qq[i].c,qq[i].d);
    //  for(int i=1;i<=n;i++) cout<<find(i)<<" ("<<g[i].first<<","<<g[i].second<<")
    ";
         
        for(int i=1,j=1,u,v,r1,r2;i<=k;i++){
            for(;j<=q[i].c && j<=n;++j) work(qq[j].a,qq[j].b,qq[j].c,qq[j].d);
            u=q[i].a,v=q[i].b,r1=find(u),r2=find(v);
            if(r1==r2){
    //          debug(u),debug(v),debug(g[u].first),debug(g[v].first),debug(g[u].second),debug(g[v].second)<<endl;
                ans[q[i].d]=abs(g[u].first-g[v].first)+abs(g[u].second-g[v].second);
            }else ans[q[i].d]=-1;
        }
    //  for(int i=1;i<=n;i++) cout<<find(i)<<" ("<<g[i].first<<","<<g[i].second<<")
    ";
        for(int i=1;i<=k;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    

      

  • 相关阅读:
    面试小结
    Everything工具使用
    记 · 工作一周年
    贝叶斯算法原理分析
    MySQL与Oracle主键Query性能测试结果
    K-meams文本聚类算法C++实现
    OPTICS光学算法
    页面添加内容后弹出框与跳转页面
    Webgrid参数格式
    页面2级分类
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6049515.html
Copyright © 2020-2023  润新知