CF508D Tanya and Password 欧拉路径
作者:互联网
题意:
分析:
- 前置芝士 :有向图欧拉路径
很容易想到把每个单词转化为一条边,把每两个字母看成一个点,一个单词相当于连接了两个点
ex : \(abc\) 相当于一条边 \(ab\to bc\)
然后判断是否存在一条欧拉路径,有向图欧拉路径的判断条件:
- 转化为无向边之后图联通
- 每个点出/入度相同,或者最多有两个点入度不等于出度,其中一个入度比出度大 \(1\) 一个出度比入度大 \(1\) 且后者必须作为起点
至于求欧拉路径的话直接 \(dfs\) 然后加点倒序输出
必须倒序输出,因为正序输出无法保证最后遍历到的点一定是终点,而倒序加点输出保证了最后访问的点一定是终点,因为只有终点无法继续向下遍历,此时就会最先入队
tip : 存边的时候必须用 \(vector\) 或者像网络流的当前弧优化一样这样才能保证复杂度,每条边只会被遍历一遍
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define mk(x,y) make_pair(x,y)
#define lc rt<<1
#define rc rt<<1|1
#define pb push_back
#define fir first
#define sec second
#define inl inline
#define reg register
using namespace std;
namespace zzc
{
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
const int maxn = 2e5+5;
int deg[maxn],fa[maxn],num[maxn],head[maxn];
int n,cnt[maxn],st;
char ch[5];
bool vis[maxn];
string ans;
vector<int> e[maxn];
void add(int u,int v)
{
e[u].pb(v);
}
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
void merge(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy) fa[fy]=fx;
}
inl int mark(char a,char b)
{
return a*128+b;
}
void dfs(int u)
{
while(cnt[u]<(int)e[u].size()) dfs(e[u][cnt[u]++]);
ans+=(char)(u%128);
}
bool check()
{
int tmp1=0,tmp2=0;
st=mark(ch[1],ch[2]);
for(int i=0;i<=17000;i++)
{
if(num[i])
{
if(find(i)==i) tmp1++;
if(deg[i])
{
if(deg[i]>1||deg[i]<-1) return false;
if(deg[i]==1) st=i;
tmp2++;
}
}
}
if(tmp1>1) return false;
if(tmp2&&tmp2!=2) return false;
return true;
}
void work()
{
n=read();
for(int i=1;i<=17000;i++) fa[i]=i;
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
add(mark(ch[1],ch[2]),mark(ch[2],ch[3]));
merge(mark(ch[1],ch[2]),mark(ch[2],ch[3]));
deg[mark(ch[1],ch[2])]++;
deg[mark(ch[2],ch[3])]--;
num[mark(ch[1],ch[2])]++;
num[mark(ch[2],ch[3])]++;
}
if(!check())
{
puts("NO");
return ;
}
else puts("YES");
dfs(st);
ans+=(char)(st/128);
reverse(ans.begin(),ans.end());
cout<<ans<<endl;
}
}
int main()
{
zzc::work();
return 0;
}
标签:return,int,void,Tanya,fa,CF508D,Password,find,欧拉 来源: https://www.cnblogs.com/youth518/p/14328550.html