C++AC,G++CE
const int MAXN = 110000;
struct Direct_Euler
{
int out[MAXN], father[MAXN];
vector<int> vt[MAXN];
stack<int> sk;
typedef pair<int, int> pii;
set<pii> st;
void init()
{
st.clear();
while (!sk.empty())
sk.pop();
REP(i, MAXN)
{
father[i] = i;
vt[i].clear();
}
CLR(out, 0);
}
int find(int n)
{
return father[n] == n ? n : father[n] = find(father[n]);
}
bool isOne(int n)
{
int t = find(0);
REP(i, n)
{
if (find(i) != t)
return false;
}
return true;
}
void merge(int a, int b)
{
vt[a].push_back(b);
out[a]++;
out[b]--;
int fa = find(a), fb = find(b);
father[fb] = fa;
}
//是返回true,而且如果是欧拉回路circle = 0,如果是欧拉路circle > 0
//不是返回false
bool isEulerRoad(int n, int& circle, int& ind)
{
if (!isOne(n))
return false;
int end = 0, same = 0;
circle = 0;
REP(i, MAXN)
{
if (out[i] == 1)
{
if (++circle > 1) return false;
ind = i;
}
else if (out[i] == -1)
end++;
else if (out[i] == 0)
same++;
}
return (circle + end + same == MAXN);
}
void dfs(int n)
{
REP(i, vt[n].size())
{
int next = vt[n][i];
if (!st.count(MP(n, next)))
{
st.insert(MP(n, next));
dfs(next);
sk.push(n);
}
}
}
} graph;
int main()
{
// freopen("in.txt", "r", stdin);
int n, ncase;
RI(ncase);
while (ncase--)
{
graph.init();
RI(n);
REP(i, n)
{
RS(ipt);
graph.merge(ipt[0] - ‘a‘ + 1000, i);
graph.merge(i, ipt[strlen(ipt) - 1] - ‘a‘ + 1000);
}
int ind, tot;
if (!graph.isEulerRoad(n, tot, ind))
puts("The door cannot be opened.");
else
puts("Ordering is possible.");
}
return 0;
}
有关有向图的欧拉回路的独立成一个结构体了原文:http://blog.csdn.net/wty__/article/details/21523795