部分代码
int n = 0, m = 0, s = -1, tot = 0; // 点的数量, 边的数量, 欧拉路径的起点(如果有的话), 链式前向星计数器
int in0[N] = {0}, out0[N] = {0}, head[N] = {0}; // head[u]: 以u为起点的第一条(未访问过的)边的位置(实为最后输入的以u为起点的边的编号)
stack<int> s0; // 存储答案的栈
struct node0
{
int u, v;
} tmp[M];
struct edge0
{
int nxt, to; // 与该边同起点的下一条边的位置; 该边的终点
} e[M];
inline void add_edge(ll u, ll v)
{
e[++tot].nxt = head[u]; // 将原来以u作为起点的第一条边, 作为该边的后续边, 第一次则指向NULL(0)
e[tot].to = v; // 该边的终点设置为v
head[u] = tot; // 更新head[u], 当前边为下一条边需要指向的边
}
bool cmp0(node0 a, node0 b)
{
if (a.u != b.u)
return a.u < b.u;
return a.v > b.v; // 链式前向星是后输入的先遍历, 所以应将终点从大到小排序
}
inline void dfs(int st)
{
for (int i = head[st]; i; i = head[st]) //i = e[i].nxt不行, 因为?
{
int v = e[i].to;
head[st] = e[i].nxt;
printf("st=%d; i=%d; head[st]=%d; e[i].nxt=%d\n", st, i, head[st], e[i].nxt);
dfs(v);
}
s0.push(st);
}
inline void init0()
{
n = read();
m = read();
for (int i = 1; i <= m; ++i)
{
tmp[i].u = read(), tmp[i].v = read();
++out0[tmp[i].u];
++in0[tmp[i].v];
}
sort(tmp + 1, tmp + 1 + m, cmp0);
for (int i = 1; i <= m; ++i)
add_edge(tmp[i].u, tmp[i].v);
}
int main()
{
init0();
bool flag = true; // 所有点的入度都等于出度
ll in = 0, out = 0; // 满足条件的起点数,和终点数
for (int i = 1; i <= n; ++i)
{
if (abs(in0[i] - out0[i]) > 1)
{
printf("No");
return 0;
}
if (out0[i] != in0[i])
flag = false;
if (in0[i] == out0[i] - 1)
{
s = i;
++in;
}
if (in0[i] - 1 == out0[i])
++out;
}
if ((!flag) && (!(in == 1 && out == 1)))
{
printf("No");
return 0;
}
else if (flag == true)
dfs(1);
else
dfs(s);
while (!s0.empty())
{
printf("%d ", s0.top());
s0.pop();
}
return 0;
}
第30行i = head[st]效果不是应该等同于i = e[i].nxt吗? 为什么换成i = e[i].nxt会多出一些额外的循环?