zoukankan      html  css  js  c++  java
  • bzoj1760 [Baltic2009]Triangulation

    给定一个多边形的三角剖分(n<=1e5),且每个三角形有其颜色,问最多可以把这个三角剖分分成几个联通的部分,使任何一种颜色不出现在多个连通块中

    建出三角剖分对应的树,同种颜色的点之间的路径是不能被切开的,因此将同色的点间路径标记一下,未标记的边数即为答案

    具体实现可以用树上差分进行标记,树链剖分lca,同色的点按dfs序排序并将排序后相邻的点间路径标记

    #include<cstdio>
    #include<algorithm>
    typedef long long i64;
    const int R=5e6,N=100007,P=1844677;
    char buf[R],*ptr=buf-1;
    int _(){
        int x=0,c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    long long hx[P];
    int hy[P];
    int n,ans=-1;
    int e[N][3],ep[N],col[N],cc[N],*cl[N],*cr[N],_c[N],*cp=_c,v[N];
    int fa[N],sz[N],son[N],dep[N],top[N],id[N],idp=0;
    void chk(int a,int b,int id){
        if(a>b)std::swap(a,b);
        i64 h=i64(a)<<20|b;
        int w=h%P;
        while(hy[w]){
            if(hx[w]==h){
                e[hy[w]][ep[hy[w]]++]=id;
                e[id][ep[id]++]=hy[w];
                return;
            }
            if((w+=12347)>=P)w-=P;
        }
        hx[w]=h;hy[w]=id;
    }
    void f1(int w,int pa){
        fa[w]=pa;
        dep[w]=dep[pa]+1;
        sz[w]=1;
        for(int i=0;i<ep[w];++i){
            int u=e[w][i];
            if(u==pa)continue;
            f1(u,w);
            sz[w]+=sz[u];
            if(sz[son[w]]<sz[u])son[w]=u;
        }
    }
    void f2(int w,int tp){
        top[w]=tp;
        id[w]=++idp;
        if(son[w])f2(son[w],tp);
        for(int i=0;i<ep[w];++i){
            int u=e[w][i];
            if(u==fa[w]||u==son[w])continue;
            f2(u,u);
        }
    }
    void f3(int w){
        for(int i=0;i<ep[w];++i){
            int u=e[w][i];
            if(u==fa[w])continue;
            f3(u);
            v[w]+=v[u];
        }
        if(!v[w])++ans;
    }
    int lca(int x,int y){
        int a=top[x],b=top[y];
        while(a!=b){
            if(dep[a]<dep[b])std::swap(a,b),std::swap(x,y);
            x=fa[a];a=top[x];
        }
        return dep[x]<dep[y]?x:y;
    }
    bool cmp(int a,int b){
        return id[a]<id[b];
    }
    int main(){
        fread(buf,1,R,stdin);
        n=_()-2;
        for(int i=1;i<=n;++i){
            int a=_(),b=_(),c=_();
            chk(a,b,i);
            chk(a,c,i);
            chk(c,b,i);
            ++cc[col[i]=_()];
        }
        for(int i=1;i<=n;++i)cl[i]=cr[i]=cp,cp+=cc[i];
        for(int i=1;i<=n;++i)*(cr[col[i]]++)=i;
        f1(1,0);
        f2(1,1);
        for(int i=1;i<=n;++i)if(cl[i]!=cr[i]){
            std::sort(cl[i],cr[i],cmp);
            for(int p=1;p<cc[i];++p){
                int x=cl[i][p],y=cl[i][p-1],z=lca(x,y);
                ++v[x];++v[y];v[z]-=2;
            }
        }
        f3(1);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    简单工作流实现思路总结
    (转)基于SAML的单点登录介绍
    Kerberos简介
    (转)Java NIO框架Mina、Netty、Grizzly介绍与对比
    职场老好人为何没发展
    如何改变、摆脱职场老好人
    线程的状态转换图
    设计模式分类
    (转)简单的RPC java实现 .
    MYSQL导入CSV格式文件数据执行提示错误(ERROR 1290): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement.
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6067629.html
Copyright © 2011-2022 走看看