Codeforces Round #288 (Div. 2) D
欧拉通路好题!!!
一开始的时候,我想了一下,不知道该怎么解决一个“中断”的问题(可能微机学多了,用了这个名词解释哈哈哈)。
如图类型:

所以,我们可以拿栈维护一下,重点就是栈,其他XJB操作都是不得正解的!!!
譬如,我们访问到了,我们访问下一个结点,然后把后继所有访问完了,也就是把后继所有的都是进栈了。于是,是不是满足了我们所要的输出欧拉通路的作用了!!!太巧了,好!
当然,不要忘记特判,假如大家都是"aaa"的时候,实际上我们要给起点定义的哟~
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define _ABS(x, y) ( x > y ? (x - y) : (y - x) )
#define lowbit(x) ( x&( -x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 4e5 + 7;
int N, In_du[maxN] = {0}, Out_du[maxN] = {0}, tot = 0, root[maxN];
inline int fid(int x) { return x == root[x] ? x : root[x] = fid(root[x]); }
char s[maxN][4], ch[maxN][2];
string tmp;
unordered_map<string, int> Hash_mp;
inline int Hash_id(char fir, char sec)
{
tmp.clear(); tmp += fir; tmp += sec;
if(Hash_mp[tmp]) return Hash_mp[tmp];
else
{
ch[++tot][0] = fir; ch[tot][1] = sec;
return Hash_mp[tmp] = tot;
}
}
int head[maxN], cnt;
struct Eddge
{
int nex, to;
Eddge(int a=-1, int b=0):nex(a), to(b) {}
}edge[maxN << 1];
inline void addEddge(int u, int v) { edge[cnt] = Eddge(head[u], v); head[u] = cnt++; }
stack<char> ans;
stack<int> S;
void dfs(int st)
{
S.push(st);
int u, v;
while(!S.empty())
{
u = S.top();
if(~head[u])
{
v = edge[head[u]].to;
head[u] = edge[head[u]].nex;
S.push(v);
}
else
{
ans.push(ch[u][1]);
S.pop();
}
}
}
inline void init()
{
tot = 0;
for(int i=0; i<=(N << 1); i++)
{
head[i] = -1;
root[i] = i;
}
}
int main()
{
scanf("%d", &N);
init();
for(int i=1, u, v, fu, fv; i<=N; i++)
{
scanf("%s", s[i]);
u = Hash_id(s[i][0], s[i][1]); v = Hash_id(s[i][1], s[i][2]);
Out_du[u]++; In_du[v]++;
addEddge(u, v);
fu = fid(u); fv = fid(v);
if(fu ^ fv) root[fu] = fv;
}
int KK = 0;
for(int i=1; i<=tot; i++) KK += (i == fid(i));
if(KK ^ 1) { printf("NO\n"); return 0; }
bool flag = true;
int st = 0, nono = 0;
for(int i=1; i<=tot; i++)
{
if(In_du[i] == Out_du[i]) continue;
if(Out_du[i] - In_du[i] == 1)
{
if(st)
{
flag = false;
break;
}
else st = i;
}
else if(Out_du[i] - In_du[i] == -1)
{
if(++nono > 1) { flag = false; break; }
}
else { flag = false; break; }
}
if(!flag) { printf("NO\n"); return 0; }
if(!st) st = 1; //全相同情况
dfs(st);
ans.push(ch[st][0]);
printf("YES\n");
while(!ans.empty())
{
printf("%c", ans.top());
ans.pop();
}
printf("\n");
return 0;
}
本文详细解析了Codeforces Round #288 (Div.2) D题的欧拉通路算法实现,通过栈维护访问顺序,解决了中断问题,实现了正确的欧拉通路输出。特别讨论了特判情况和具体代码实现细节。
1370

被折叠的 条评论
为什么被折叠?



