• CF508D


    题解

    考虑把每一个串的前两位和后两位分别看成一个点(字符串哈希),从前向后连边,问题转化成求所建图的欧拉路径。
    对于有向图的欧拉路径,常规操作请移步P7771 【模板】欧拉路径
    对于本题而言,有一点易错的细节:

    • 有自环,重边,所以点数我开到 (256 imes 256),但边数还是 (2 imes 10^5)
    • 图可能不连通,所以加上一条判断,如果栈内元素是 (n+1) 个才有解。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define FCC fclose(stdin),fclose(stdout)
    const int INF = 0x3f3f3f3f,base=256,N = 257*257;
    inline ll read()
    {
    	ll ret=0;char ch=' ',c=getchar();
    	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
    	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
    	return ch=='-'?-ret:ret;
    }
    int n;
    int head[N],ecnt=-1;
    int ind[N],oud[N];
    inline void init_edge(){memset(head,-1,sizeof(head)),ecnt=-1;}
    struct edge
    {
    	int nxt,to;
    }a[200005];
    bool vis[N];
    inline void add_edge(int x,int y)
    {
    	a[++ecnt]=(edge){head[x],y};
    	head[x]=ecnt;
    	ind[y]++,oud[x]++;
    	vis[x]=1,vis[y]=1;
    }
    
    int S,T,stk[N],top;
    char str[N][3];
    void dfs(int u)
    {
    	for(int i=head[u];~i;i=head[u])
    	{
    		int v=a[i].to;
    		head[u]=a[i].nxt;//链前的删边操作 
    		dfs(v);
    	}
    	stk[++top]=u;
    }
    int main()
    {
    	init_edge();
    	n=read();
    	for(int i=1;i<=n;i++)	
    	{
    		char s[6];
    		scanf("%s",s+1);
    		int u=(s[1]-'0'+1)*base+s[2]-'0'+1;
    		int v=(s[2]-'0'+1)*base+s[3]-'0'+1;
    		add_edge(u,v);
    		str[u][1]=s[1],str[u][2]=s[2];
    		str[v][1]=s[2],str[v][2]=s[3];
    		//cout<<str[u]<<'
    ';
    		//printf("%d->%d
    ",u,v);
    		S=u;
    	}
    	int cnt=0;
    	for(int i=0;i<=256*256;i++)
    	{
    		if(!vis[i]) continue;
    		if(oud[i]-ind[i]==1) S=i;
    		if(oud[i]-ind[i]==-1) T=i;
    		if(abs(oud[i]-ind[i])>1) return puts("NO"),0;
    		cnt+=(oud[i]!=ind[i]);
    	}
    	if(cnt!=2&&cnt) return puts("NO"),0;
    	
    	dfs(S);
    	//printf("S=%d,top=%d
    ",S,top);
    	if(top+1!=n+2) return puts("NO"),0;
    	bool fir=0;
    	puts("YES");
    	while(top) 
    	{
    		if(!fir) printf("%c",str[stk[top]][1]),fir=1;
    		printf("%c",str[stk[top]][2]),top--;
    	}
    	return 0;
    }
    
  • 相关阅读:
    PC端Vue后台管理系统request.js结合业务封装axios
    从零开始学 Web 之 Vue.js(五)Vue的动画
    css实现左右两个div等高
    css样式优先级计算规则
    jquery中attr和prop区别
    table文字溢出显示省略号问题
    2020-12-15
    2020-12-14
    2020-12-11
    2020-12-10
  • 原文地址:https://www.cnblogs.com/conprour/p/15532958.html
Copyright © 2020-2023  润新知