508D (欧拉路)

题目大意:n个长度为3的串,串abc,def能够连接在一起当且仅当b=d,c=e。问能否将这n个串拼接得到长度为n+2的串。

可将每一个串视为一条边,前两个字符与后两个字符分别为顶点。则问题转化为有向图中求欧拉路。
注意由于可能会出现重边以及环,用邻接矩阵存储时,每出现一条边,数量加1,遍历删边的时候减1即可

欧拉回路、欧拉路存在的判定:

1、欧拉路:
                无向图:连通。度数为奇数的顶点个数为0或2。
                有向图:基图连通。所有顶点的入度等于出度,或者有且仅有一个顶点入度-出度=1,有且仅有一个顶点出度-入度=1。
2、欧拉回路:
                无向图:连通。度数为奇数的顶点个数为0。
                有向图:基图连通。所有顶点的入度等于出度。

找欧拉路(或回路)可以用Fleury算法。http://blog.csdn.net/yang_7_46/article/details/7871760
其本质就是遍历每一条边。

 

#include<bits/stdc++.h>
using namespace std;
#define maxn 62*62

int n,m=0,ans[200005],edge[maxn][maxn],in[maxn],out[maxn],max_n=0,min_n=maxn,start=-1;
int change(char a)
{
    if('0'<=a&&a<='9') return a-'0';
    if('a'<=a&&a<='z') return a-'a'+10;
    return a-'A'+36;
}

char change(int a)
{
    if(a<10) return a+'0';
    if(a<36) return a+'a'-10;
    return a+'A'-36;
}

bool judge()
{
    int i;
    for(i=min_n;i<=max_n;++i)
    {
        if(abs(out[i]-in[i])>1) return 0;
        if(out[i]>in[i])
        {
            if(start!=-1) return 0;
            start=i;
        }
    }
    if(start==-1) for(i=min_n;i<=max_n;++i) if(out[i]) {start=i;break;}
    return 1;
}

void dfs(int x)
{
    for(int i=min_n;i<=max_n;++i)
    {
        while(edge[x][i])
        {
            edge[x][i]--;
            dfs(i);
            ans[m++]=i;
        }
    }
}

void output()
{
    for(int i=m;i>=0;--i)
    {
        if(i==m) cout<<change(ans[i]/62)<<change(ans[i]%62);
        else cout<<change(ans[i]%62);
    }
    cout<<endl;
}
int main()
{
    int i;
    char s[5];
    cin>>n;
    memset(out,0,sizeof(out));
    memset(in,0,sizeof(in));
    memset(edge,0,sizeof(edge));
    for(i=1;i<=n;++i)
    {
        cin>>s;
        int x=change(s[0])*62+change(s[1]);
        int y=change(s[1])*62+change(s[2]);
        edge[x][y]++;
        max_n=max(max(max_n,x),y);
        min_n=min(min(min_n,x),y);
        out[x]++,in[y]++;
    }
    if(judge())
    {
        dfs(start);
        ans[m]=start;
        if(m==n) {puts("YES");output();}
        else puts("NO");
    }
    else puts("NO");
    return 0;
}


 

你可能感兴趣的:(508D (欧拉路))