codeforces 508D (無向圖尤拉路徑)
阿新 • • 發佈:2019-01-06
題意:給出n個單詞(長度為3),求出一種頭尾相連的方案。兩個單詞能連起來當且僅當前一個單詞的後兩位和後一個單詞的前兩位相同。
直接把每個單詞看成邊,前兩位和後兩位看成點,跑尤拉路徑即可。需要一些優化把尤拉路徑改成線性。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:102400000,102400000")
#define Clear(x,y) memset (x,y,sizeof(x))
#define Close() ios::sync_with_stdio(0)
#define Open() freopen ("more.in", "r", stdin)
#define get_min(a,b) a = min (a, b)
#define get_max(a,b) a = max (a, b);
#define y0 yzz
#define y1 yzzz
#define fi first
#define se second
#define pii pair<int, int>
#define pli pair<long long, int>
#define pll pair<long long, long long>
#define pb push_back
#define pl c<<1
#define pr (c<<1)|1
#define lson tree[c].l,tree[c].mid,pl
#define rson tree[c].mid+1,tree[c].r,pr
#define mod 1000000007
typedef unsigned long long ull;
template <class T> inline T lowbit (T x) {return x&(-x);}
template <class T> inline T sqr (T x) {return x*x;}
template <class T>
inline bool scan (T &ret) {
char c;
int sgn;
if (c = getchar(), c == EOF) return 0; //EOF
while (c != '-' && (c < '0' || c > '9') ) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
const double pi = 3.14159265358979323846264338327950288L;
using namespace std;
#define INF 1e17
#define maxn 100005
#define maxm 1000005
//-----------------morejarphone--------------------//
struct node {
int v;
string s;
bool vis;
};
vector <node> g[maxn];
int from[maxn];
vector <string> ans;
map <string, int> gg;
int n, cnt;
int in[maxn], out[maxn];
void dfs (int u) { //cout << u << endl;
int sz = g[u].size ();
for (int i = from[u]; i < sz; i++) {
if (!g[u][i].vis) {
g[u][i].vis = 1;
from[u] = i+1;
dfs (g[u][i].v);
ans.pb (g[u][i].s);
}
else break;
}
}
char str[maxn];
int main () {
//freopen ("more.in", "r", stdin);
scanf ("%d", &n);
gg.clear ();
Clear (in, 0);
Clear (out, 0);
Clear (from, 0);
int s = 0;
cnt = 0;
for (int i = 0; i < maxn; i++) g[i].clear ();
for (int i = 0; i < n; i++) {
scanf ("%s", str);
string tmp = (string) str;
string uu = ""; uu += tmp[0], uu += tmp[1];
string vv = ""; vv += tmp[1], vv += tmp[2];
int u, v;
if (!gg.count (uu)) {
gg[uu] = cnt++;
u = gg[uu];
}
else u = gg[uu];
if (!gg.count (vv)) {
gg[vv] = cnt++;
v = gg[vv];
}
else v = gg[vv];
g[u].pb ((node) {v, tmp, 0});
in[v]++; out[u]++;
s = u;
}
int x = 0, y = 0;
for (int i = 0; i < cnt; i++) {
if (out[i]-in[i] == 1) {
x++;
s = i;
}
else if (in[i]-out[i] == 1) y++;
else if (abs (in[i]-out[i]) > 1) {
printf ("NO\n");
return 0;
}
}
if ((x^y) || x > 1 || y > 1) {
printf ("NO\n");
return 0;
}
ans.clear ();
dfs (s);
if (ans.size () != n) {
printf ("NO\n");
return 0;
}
printf ("YES\n");
for (int i = n-1; i >= 0; i--) {
if (i == n-1) printf ("%c%c%c", ans[i][0], ans[i][1], ans[i][2]);
else printf ("%c", ans[i][2]);
}
puts ("");
return 0;
}