P r o b l e m \mathrm{Problem} Problem
S o l u t i o n \mathrm{Solution} Solution
一眼欧拉路,关键在于如何建图才能正确的跑出欧拉路。
观察到我们不能两两匹配是否相连去欧拉路,不仅建图不允许,点的欧拉路也难以有解。因此我们可以从单个字符串上考虑如何建图。
发现有效信息只有开头字母 s s s和结尾字母 e e e,那么我们直接的建图也是和这两个字母相关。如果我们直接从建立边 ( s , e , i ) (s,e,i) (s,e,i)很难与其他边对接起来。我们考虑 e e e在melody中的下一个字母 next \text{next} next,我们建立 ( s , n e x t , i ) (s,\mathrm{next},i) (s,next,i)跑欧拉回路即可。
仔细想想发现是对的,真的好妙好妙好妙…
C o d e \mathrm{Code} Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5;
int n, cnt;
int res[N];
string S[N];
vector < pair<int, int> > a[N];
char melody[6] = {'m', 'e', 'l', 'o', 'd', 'y'};
void MakeEdge(int t, string x)
{
char st = x[0];
int len = x.size();
char ed = x[len - 1];
for (int i=0;i<6;++i)
if (ed == melody[i]) {
ed = melody[(i + 1) % 6];
break;
}
a[st].push_back({ed, t});
}
void Dfs(int x)
{
while (a[x].size())
{
int S = a[x].size();
int y = a[x][S-1].first;
int t = a[x][S-1].second;
a[x].pop_back();
Dfs(y);
res[++ cnt] = t;
}
return;
}
int main(void)
{
freopen("melody5.in","r",stdin);
cin >> n;
for (int i=1;i<=n;++i) {
cin >> S[i];
MakeEdge(i, S[i]);
}
Dfs('m');
for (int i=n;i>=1;--i) printf("%d ", res[i]);
return 0;
}