zoukankan      html  css  js  c++  java
  • 「POI2012」约会 Rendezvous

    #2691. 「POI2012」约会 Rendezvous

    这题我简直不想说什么了,什么素质,卡常数……

    “每个顶点有且仅有一条出边”,所以是一道基环树的题,首先tarjan缩点,在缩完点后的图上求a,b的LCA,如果LCA在环内,求出a,b分别对应环中的哪一个点,显然这两个点中的一个为最优解。

    我一开始是在求LCA时顺便求出的a,b对应的点,这样使常数变大,虽然在LOJ和bzoj上都A了,但是在某OJ上疯狂T94,调了一下午+一晚上……

    这个可以提前一边dfs预处理出来:

     1 void dfs2(int x,int ci,int ff)
     2 {
     3     incir[x]=ci;
     4     for(int i=f(x);i;i=n(i))
     5     if(v(i)!=ff && belong[v(i)]!=belong[x])
     6         dfs2(v(i),ci,x);
     7 }
     8 
     9 for(int i=1;i<=tot;i++)
    10     if(scc[i].size()>1)
    11         for(int j=0;j<scc[i].size();j++)
    12             dfs2(scc[i][j],scc[i][j],d[scc[i][j]]);

    感谢ooo帮忙卡常以及mikufun大佬提醒。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #define rint register int
    #define MAXN 500010
    #define ma(x) memset(x,0,sizeof(x))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int L=1<<20|1;
    char buffer[L],*S,*T;
    #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
    using namespace std;
    struct edge
    {
        int u,v,nxt;
        #define u(x) ed[x].u
        #define v(x) ed[x].v
        #define n(x) ed[x].nxt
        #define v2(x) ed2[x].v
        #define n2(x) ed2[x].nxt
    }ed[MAXN],ed2[MAXN];
    int first[MAXN],num_e;
    #define f(x) first[x]
    int first2[MAXN],num_e2;
    #define f2(x) first2[x]
    
    int n,k;
    int d[MAXN];
    inline void add(rint u,rint v);
    inline void add2(rint u,rint v);
    inline void swap(rint *a,rint* b)
    {
        *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
    }
    inline int read()
    {
        int s=0;char a=getchar();
        while(a<'0'||a>'9')a=getchar();
        while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
        return s;
    }
    int dfn[MAXN],low[MAXN],cnt;
    int stack[MAXN],top;
    bool vi[MAXN];
    int tot,belong[MAXN];
    vector<int> scc[MAXN];
    int sor[MAXN],ooo;
    int intree[MAXN],tr;
    void tarjan(int x)
    {
        dfn[x]=++cnt;low[x]=cnt;
        vi[x]=1;
        stack[++top]=x;
        for(rint i=f(x);i;i=n(i))
            if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
            else if(vi[v(i)])low[x]=min(low[x],low[v(i)]);
        if(dfn[x]==low[x])
        {
            tot++;vi[x]=0;ooo=0;
            while(stack[top]!=x)
            {
                belong[stack[top]]=tot;
                scc[tot].push_back(stack[top]);
                sor[stack[top]]=++ooo;
                vi[stack[top--]]=0;
            }
            sor[stack[top]]=++ooo;
            scc[tot].push_back(stack[top]);
            belong[stack[top--]]=tot;
        }
    }
    
    int dep[MAXN],fa[MAXN][21];
    int bin[21];
    void dfs(int x,int ff,int de,int tr)
    {
        fa[x][0]=ff;dep[x]=de;intree[x]=tr;
        for(rint i=f2(x);i;i=n2(i))
            if(v2(i)!=ff && !dep[v2(i)])
                dfs(v2(i),x,de+1,tr);
    }
    int LCA(int a,int b,int x,int y,int &xi,int &yi,int &xx,int &yy)
    {
        xi=yi=0;xx=a;yy=b;
        bool pd=0;
        if(dep[x]>dep[y]){swap(x,y);swap(xx,yy);pd=1;}
        if(dep[x]!=dep[y])
        {
            while(dep[x]!=dep[y]-1)
                for(rint i=0;;i++)
                if(dep[fa[y][i]]-1<dep[x])
                {y=fa[y][i-1];yi+=bin[i-1];break;}
            yy=scc[y][0];yy=d[yy];
            y=fa[y][0],yi++;
        }
        if(x==y)
        {
            if(pd){swap(xi,yi);swap(xx,yy);}
            return y;
        }
        while(fa[x][0]!=fa[y][0])
            for(rint i=0;;i++)
            if(fa[x][i]==fa[y][i])    
            {x=fa[x][i-1],y=fa[y][i-1];xi+=bin[i-1],yi+=bin[i-1];break;}
        if(pd){swap(xi,yi);swap(x,y);}++xi,++yi;
        xx=d[scc[x][0]],yy=d[scc[y][0]];
        return fa[x][0];
    }
    int du[MAXN];
    signed main()
    {
    //    freopen("1.in","r",stdin);
    //    freopen("in.txt","r",stdin);
    
        bin[0]=1;for(rint i=1;i<20;i++)bin[i]=bin[i-1]<<1;
        n=read(),k=read();
        for(rint i=1;i<=n;i++){d[i]=read();add(d[i],i);}
        for(rint i=1;i<=n;i++)
            if(!dfn[i])tarjan(i);
        for(rint i=1;i<=num_e;i++)
            if(belong[u(i)]!=belong[v(i)])
                add2(belong[u(i)],belong[v(i)]),du[belong[v(i)]]++;
        for(rint i=1;i<=tot;i++)
            if(!du[i])dfs(i,0,1,++tr);
        for(rint i=1;i<20;i++)
            for(rint j=1;j<=tot;j++)
                fa[j][i]=fa[fa[j][i-1]][i-1];
        int a,b,xi,yi,xx,yy;
        int lca,t1,t2,x1,x2,y1,y2;
        for(rint i=1;i<=k;i++)
        {
            a=read(),b=read();
            if(intree[belong[a]]!=intree[belong[b]]){puts("-1 -1");continue;}
            lca=LCA(a,b,belong[a],belong[b],xi,yi,xx,yy);
            if(!lca){puts("-1 -1");continue;}
            if(scc[lca].size()==1){printf("%d %d
    ",xi,yi);continue;}
            t1=(sor[xx]-sor[yy]+scc[belong[xx]].size()),
            t2=(sor[yy]-sor[xx]+scc[belong[xx]].size());
            if(t1>=scc[belong[xx]].size())t1-=scc[belong[xx]].size();
            if(t2>=scc[belong[xx]].size())t2-=scc[belong[xx]].size();
            swap(t1,t2);
            x1=xi,y1=yi+t2;
            x2=xi+t1,y2=yi;
            int ma1=max(x1,y1),ma2=max(x2,y2),mi1=min(x1,y1),mi2=min(x2,y2);
            if(ma1!=ma2){ma1<ma2?printf("%d %d
    ",x1,y1):printf("%d %d
    ",x2,y2);}
            else if(mi1!=mi2){mi1<mi2?printf("%d %d
    ",x1,y1):printf("%d %d
    ",x2,y2);}
            else{x1>=y1?printf("%d %d
    ",x1,y1):printf("%d %d
    ",x2,y2);}
        }
    }
    inline void add(rint u,rint v)
    {
        u(++num_e)=u;
        v(num_e)=v;
        n(num_e)=f(u);
        f(u)=num_e;
    }
    inline void add2(rint u,rint v)
    {
        v2(++num_e2)=v;
        n2(num_e2)=f2(u);
        f2(u)=num_e2;
    }
    疯狂T94的沙雕代码
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #define rint register int
    #define MAXN 500010
    #define ma(x) memset(x,0,sizeof(x))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int L=1<<20|1;
    char buffer[L],*S,*T;
    #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
    using namespace std;
    struct edge
    {
        int u,v,nxt;
        #define u(x) ed[x].u
        #define v(x) ed[x].v
        #define n(x) ed[x].nxt
        #define v2(x) ed2[x].v
        #define n2(x) ed2[x].nxt
    }ed[MAXN],ed2[MAXN];
    int first[MAXN],num_e;
    #define f(x) first[x]
    int first2[MAXN],num_e2;
    #define f2(x) first2[x]
    
    int n,k;
    int d[MAXN];
    inline void add(rint u,rint v);
    inline void add2(rint u,rint v);
    inline void swap(rint *a,rint* b)
    {
        *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
    }
    inline int read()
    {
        int s=0;char a=getchar();
        while(a<'0'||a>'9')a=getchar();
        while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
        return s;
    }
    int dfn[MAXN],low[MAXN],cnt;
    int stack[MAXN],top;
    bool vi[MAXN];
    int tot,belong[MAXN];
    vector<int> scc[MAXN];
    int sor[MAXN],ooo;
    int intree[MAXN],tr;
    int incir[MAXN],ci;
    void tarjan(int x)
    {
        dfn[x]=++cnt;low[x]=cnt;
        vi[x]=1;
        stack[++top]=x;
        for(rint i=f(x);i;i=n(i))
            if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
            else if(vi[v(i)])low[x]=min(low[x],low[v(i)]);
        if(dfn[x]==low[x])
        {
            tot++;vi[x]=0;ooo=0;
            while(stack[top]!=x)
            {
                belong[stack[top]]=tot;
                scc[tot].push_back(stack[top]);
                sor[stack[top]]=++ooo;
                vi[stack[top--]]=0;
            }
            sor[stack[top]]=++ooo;
            scc[tot].push_back(stack[top]);
            belong[stack[top--]]=tot;
        }
    }
    
    int dep[MAXN],fa[MAXN][21];
    int bin[21];
    void dfs(int x,int ff,int de,int tr)
    {
        fa[x][0]=ff;dep[x]=de;intree[x]=tr;
        for(rint i=f2(x);i;i=n2(i))
            if(v2(i)!=ff && !dep[v2(i)])
                dfs(v2(i),x,de+1,tr);
    }
    void dfs2(int x,int ci,int ff)
    {
        incir[x]=ci;
        for(int i=f(x);i;i=n(i))
        if(v(i)!=ff && belong[v(i)]!=belong[x])
            dfs2(v(i),ci,x);
    }
    int LCA(int x,int y)
    {
        if(dep[x]>dep[y])swap(x,y);
            while(dep[x]!=dep[y])
                for(rint i=0;;i++)
                if(dep[fa[y][i]]<dep[x])
                {y=fa[y][i-1];break;}
        if(x==y){return y;}
        while(fa[x][0]!=fa[y][0])
            for(rint i=0;;i++)
            if(fa[x][i]==fa[y][i])    
            {x=fa[x][i-1],y=fa[y][i-1];break;}
        return fa[x][0];
    }
    int du[MAXN];
    signed main()
    {
    //    freopen("1.in","r",stdin);
    //    freopen("in.txt","r",stdin);
    
        bin[0]=1;for(rint i=1;i<20;i++)bin[i]=bin[i-1]<<1;
        n=read(),k=read();
        for(rint i=1;i<=n;i++){d[i]=read();add(d[i],i);}
        for(rint i=1;i<=n;i++)
            if(!dfn[i])tarjan(i);
        for(rint i=1;i<=num_e;i++)
            if(belong[u(i)]!=belong[v(i)])
                add2(belong[u(i)],belong[v(i)]),du[belong[v(i)]]++;
        for(rint i=1;i<=tot;i++)
            if(!du[i])dfs(i,0,1,++tr);
        for(rint i=1;i<20;i++)
            for(rint j=1;j<=tot;j++)
                fa[j][i]=fa[fa[j][i-1]][i-1];
        for(int i=1;i<=tot;i++)
        if(scc[i].size()>1)
            for(int j=0;j<scc[i].size();j++)
                dfs2(scc[i][j],scc[i][j],d[scc[i][j]]);
        int a,b,xi,yi,xx,yy;
        int lca,t1,t2,x1,x2,y1,y2;
        for(rint i=1;i<=k;i++)
        {
            a=read(),b=read();
            if(intree[belong[a]]!=intree[belong[b]]){puts("-1 -1");continue;}
            if(incir[a]==incir[b])
            {
                lca=LCA(belong[a],belong[b]);
                printf("%d %d
    ",dep[belong[a]]-dep[lca],dep[belong[b]]-dep[lca]);
                continue;
            }
            else
                xx=incir[a],yy=incir[b],xi=dep[belong[a]]-dep[belong[incir[a]]],yi=dep[belong[b]]-dep[belong[incir[b]]];
            t1=(sor[xx]-sor[yy]+scc[belong[xx]].size()),
            t2=(sor[yy]-sor[xx]+scc[belong[xx]].size());
            if(t1>=scc[belong[xx]].size())t1-=scc[belong[xx]].size();
            if(t2>=scc[belong[xx]].size())t2-=scc[belong[xx]].size();
            swap(t1,t2);
            x1=xi,y1=yi+t2;
            x2=xi+t1,y2=yi;
            int ma1=max(x1,y1),ma2=max(x2,y2),mi1=min(x1,y1),mi2=min(x2,y2);
            if(ma1!=ma2){ma1<ma2?printf("%d %d
    ",x1,y1):printf("%d %d
    ",x2,y2);}
            else if(mi1!=mi2){mi1<mi2?printf("%d %d
    ",x1,y1):printf("%d %d
    ",x2,y2);}
            else{x1>=y1?printf("%d %d
    ",x1,y1):printf("%d %d
    ",x2,y2);}
        }
    }
    inline void add(rint u,rint v)
    {
        u(++num_e)=u;
        v(num_e)=v;
        n(num_e)=f(u);
        f(u)=num_e;
    }
    inline void add2(rint u,rint v)
    {
        v2(++num_e2)=v;
        n2(num_e2)=f2(u);
        f2(u)=num_e2;
    }
    改完后的AC代码
    波澜前,面不惊。
  • 相关阅读:
    WSP部署错误—SharePoint管理框架中的对象“SPSolutionLanguagePack Name=0”依赖其他不存在的对象
    Elevate Permissions To Modify User Profile
    Error with Stsadm CommandObject reference not set to an instance of an object
    ASP.NET MVC3添加Controller时没有Scaffolding options
    测试使用Windows Live Writer写日志
    配置TFS 2010出现错误—SQL Server 登录的安全标识符(SID)与某个指定的域或工作组帐户冲突
    使用ADO.NET DbContext Generator出现错误—Unable to locate file
    CSS
    HTML DIV标签
    数据库
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11172830.html
Copyright © 2011-2022 走看看