题面
题解
- 不能从$1$开始,因为$1$可能不和别的联通,随便选一个有边的点开始。
- 注意当前弧优化(就是把已经用过的边删掉的过程),没有会超时。
- 注意原图不连通的情况,$s.size()<m$,应该算无解。
#include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 100050 #define ri register int using namespace std; int t; int n,m,u,v; stack<int> s; int cur[N]; int rd[N],cd[N],deg[N]; vector<int> ed[N],vv,to; inline int read() { int ret=0,f=0; char ch=getchar(); while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar(); return f?-ret:ret; } void add_edge(int u,int v) { to.push_back(v); vv.push_back(0); ed[u].push_back(to.size()-1); to.push_back(u); vv.push_back(0); ed[v].push_back(to.size()-1); deg[u]++; deg[v]++; } void add(int u,int v) { to.push_back(v); vv.push_back(0); ed[u].push_back(to.size()-1); rd[v]++; cd[u]++; } void euler1(int x) { for (ri &i=cur[x];i<ed[x].size();i++) { int e=ed[x][i]; if (vv[e]) continue; vv[e]=vv[1^e]=1; euler1(to[e]); s.push((e&1)?-(e/2+1):e/2+1); } } void euler2(int x) { for (ri &i=cur[x];i<ed[x].size();i++) { int e=ed[x][i]; if (vv[e]) continue; vv[e]=1; euler2(to[e]); s.push(e+1); } } int main(){ t=read(); n=read(); m=read(); memset(cur,0,sizeof(cur)); if (t==1) { for (ri i=1;i<=m;i++) { u=read(),v=read(); add_edge(u,v); } for (ri i=1;i<=n;i++) if (deg[i]&1) { puts("NO"); return 0; } euler1(u); if (s.size()<m) { puts("NO"); return 0; } puts("YES"); while (!s.empty()) printf("%d ",s.top()),s.pop(); } else { for (ri i=1;i<=m;i++) { u=read(),v=read(); add(u,v); } for (ri i=1;i<=n;i++) if (rd[i]^cd[i]) { puts("NO"); return 0; } euler2(u); if (s.size()<m) { puts("NO"); return 0; } puts("YES"); while (!s.empty()) printf("%d ",s.top()),s.pop(); } return 0; }