zoukankan      html  css  js  c++  java
  • BZOJ 1562 变换序列

    妙啊。。。。。O(N)算法。

    首先每个<n的点只连两条边。那么这就是一个环套树啊。。。。。

    然后找到在环上编号最小的点,向最小的方向更新答案。一个联通块确定了一对,就确定了这个联通块所有的样子。

    所以两遍dfs就好了。23333333orz blutrex。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 10050
    #define maxv 20050
    #define maxe 100500
    using namespace std;
    int n,d[maxn],g[maxv],nume=1,deg[maxv],ret=0,ans[maxn],dis[maxv],pre[maxv];
    int stack1[maxv],stack2[maxv],top=0;
    struct edge
    {
        int v,nxt;
    }e[maxe];
    bool vis[maxv],lab[maxv];
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs1(int x,int fath)
    {
        vis[x]=true;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (vis[v])
            {
                if (v==fath)
                {
                    if (i!=(pre[x]^1)) stack1[++top]=x,stack2[top]=v;
                    else continue;
                }
                else if (dis[v]<dis[x]) stack1[++top]=x,stack2[top]=v;
            }
            else {dis[v]=dis[x]+1;pre[v]=i;dfs1(v,x);}
        }
    }
    void dfs2(int x,int type)
    {
        vis[x]=true;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (vis[v]) continue;
            if (!type) {ans[x]=v-n;dfs2(v,type^1);}
            else dfs2(v,type^1);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=0;i<n;i++) ans[i]=-1;
        for (int i=0;i<n;i++)
        {
            scanf("%d",&d[i]);
            addedge(i,(i+d[i])%n+n);addedge((i+d[i])%n+n,i);
            addedge(i,(i-d[i]+n)%n+n);addedge((i-d[i]+n)%n+n,i);
            deg[i]+=2;deg[(i+d[i])%n+n]++;deg[(i-d[i]+n)%n+n]++;
        }
        for (int i=0;i<2*n;i++)
            if (!vis[i]) dfs1(i,-1);
        for (int i=1;i<=top;i++)
        {
            int now=stack1[i];
            while (now!=stack2[i]) 
            {
                lab[now]=true;
                now=e[pre[now]^1].v;
            }
            lab[stack2[i]]=true;
        }
        memset(vis,false,sizeof(vis));
        for (int i=0;i<n;i++)
        {
            if (!lab[i]) continue;
            if (vis[i]) continue;
            int mn=3*n;
            for (int j=g[i];j;j=e[j].nxt)
                mn=min(mn,e[j].v);
            ans[i]=mn-n;vis[i]=true;dfs2(mn,1);
        }
        for (int i=0;i<n;i++) if (ans[i]==-1) {printf("No Answer");return 0;}
        for (int i=0;i<n-1;i++) printf("%d ",ans[i]);printf("%d",ans[n-1]);
        return 0;
    }
  • 相关阅读:
    美国常青小组:“4+2”,成功的企业的普遍特征
    与你的商业伙伴建立信任关系的12条准则
    成功12级跳:你还是穷人只因为你没有立下成为富人的目标
    生日与谁共
    猎取人心的36条黄金法则
    谢谢你能为我落泪
    要锤炼出营销魔法,口碑营销“无招胜有招”
    怎样成为下一个比尔·盖茨?总结决定他成功的几大要素
    只要你能够幸福
    史玉柱:创业不是靠忽悠,我的最后四个忠告
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5919296.html
Copyright © 2011-2022 走看看