zoukankan      html  css  js  c++  java
  • 无序字母对

    传送门

    一道非常不错的欧拉回路(路径)题……

    我们已经知道怎么求欧拉回路(路径)了,但是如果求字典序最小的呢?

    求欧拉回路是一个深搜的过程……所以我们不如每次在向下一个点深搜的时候,每次让他先走那个字典序最小的节点,这样我们就能保证字典序最小了。不过实际上这个用邻接表实现会很麻烦。我的实现方法是,对于所有的边,我们先把它拆成两条有向边,对于拆出来的边赋予相同的id,之后我们把边按照起始点和终点排个序(注意邻接表的存储方法,终点要倒着排序),然后跑欧拉路径即可。

    这道题中,因为我们要一个长为n+1的字符串满足n个字符对都出现过且仅出现一次,那我们就相当于是把每个字符对看成一条边,在这个图上求欧拉路径(回路),所以一开始要先判定它能否有欧拉路径(回路),之后就正常dfs。

    对于起始点的选择有些神奇。我们不是每次都取最小的就行,因为如果要是求欧拉路径的话,我们必须强制选编号最小的奇点开始,如果要是求欧拉回路直接从最小的点开始即可。

    这种题其实用邻接矩阵方便……而且好像这个数据范围邻接矩阵和邻接表跑的一样快。

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 20005;
    const int INF = 1000000009;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    struct edge
    {
        int next,to,from,id;
        bool operator < (const edge &g) const
        {
            if(from != g.from) return from < g.from;
            else return to > g.to;
        }
    }e[M<<1],q[M<<1];
    
    int n,head[M],x,y,z,deg[M],ecnt = 1,minn = 100000,mpos = 100000,cnt,ans[M],tot;
    char s[10];
    bool vis[M];
    
    void add(int x,int y,int z)
    {
        e[++ecnt].to = y;
        e[ecnt].next = head[x];
        e[ecnt].id = z;
        e[ecnt].from = x;
        head[x] = ecnt;
    }
    
    void dfs(int x)
    {
        for(int &i = head[x];i;i = e[i].next)
        {
        int k = e[i].to,j = e[i].id;
        if(!vis[j])
        {
            vis[j] = 1;
            dfs(k);
            ans[++cnt] = k;
        }
        }
    }
    
    int main()
    {
        n = read();
        rep(i,1,n)
        {
        scanf("%s",s);
        q[i].from = q[i+n].to = s[0] - 'A' + 1;
        q[i].to = q[i+n].from = s[1] - 'A' + 1;
        q[i].id = q[i+n].id = i;
        }
        sort(q+1,q+1+(n<<1));
        rep(i,1,n<<1)
        {
        x = q[i].from,y = q[i].to,z = q[i].id;
        add(x,y,z),deg[x]++,deg[y]++;
        }
        //rep(i,1,100) printf("%d ",deg[i]);enter;
        rep(i,1,100) if((deg[i]>>1)&1) tot++;
        if(tot > 2)
        {
        printf("No Solution
    ");
        return 0;
        }
        rep(i,1,100) if(i < mpos && (deg[i]>>1) & 1) mpos = i;
        if(mpos == 100000) ans[++cnt] = q[1].from,dfs(q[1].from);
        else ans[++cnt] = mpos,dfs(mpos);
        if(cnt != n+1) printf("No Solution
    ");
        else
        {
        printf("%c",ans[1]+'A'-1);
        per(i,cnt,2) printf("%c",ans[i]+'A'-1);
        }
        return 0;
    }
  • 相关阅读:
    PCL中分割_欧式分割(1)
    如何在ROS中使用PCL(2)
    PCL超体聚类
    PCL常见错误集锦
    cv_bridge中的编码模式与实现
    Centos 安装配置gerrit
    git merge git pull时候遇到冲突解决办法git stash
    Python 虚拟环境:Virtualenv
    配置gitlab gerrit jenkins
    selinux开启关闭
  • 原文地址:https://www.cnblogs.com/captain1/p/9764239.html
Copyright © 2011-2022 走看看