有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。
一共两个子任务:
- 这张图是无向图。50( 分)
- 这张图是有向图。50( 分)
第一行一个整数 t,表示子任务编号。t∈{1,2},如果 t=1 则表示处理无向图的情况,如果 t=2 则表示处理有向图的情况。
第二行两个整数 n,m,表示图的结点数和边数。
接下来 m 行中,第 i 行两个整数 vi,ui,表示第 i 条边(从 1 开始编号),保证 1 ≤ vi,ui ≤ n。
如果 t=1 则表示 vi 到 ui 有一条无向边。
如果 t=2 则表示 vi 到 ui 有一条有向边。
图中可能有重边也可能有自环。
输出格式如果不可以一笔画,输出一行 “NO”。
否则,输出一行 “YES”,接下来一行输出一组方案。
如果 t=1,输出 m 个整数 p1,p2,…,pm。令 e=∣pi∣,那么 e 表示经过的第 i 条边的编号。如果 pi 为正数表示从 ve 走到 ue,否则表示从 ue 走到 ve。
如果 t=2,输出 m 个整数 p1,p2,…,pm。其中 pi 表示经过的第 i 条边的编号。
【样例输入1】 1 3 3 1 2 2 3 1 3 【样例输出1】 YES 1 2 -3 【样例输入2】 2 5 6 2 3 2 5 3 4 1 2 4 2 5 1 【样例输出】 YES 4 1 3 5 2 6思路
- 欧拉回路的模板,但只能算一个环,图原本可能不连通。 另外会有很多自环,也要优化一下,否则会超时。
- 有向图的欧拉回路就是入度与出度之和一定是一个偶数(如果入度为1,出度为-1,和为0),无向图的点度一定是偶数,用这个来判断是否为欧拉回路。
应该是没有优化很多自环的情况
#includeAC_Code#define ll long long #include #include #define db double #define ls p<<1 #define rs p<<1|1 using namespace std; const int N=100010, M=1000010; inline ll read() { char c=getchar(); int x=0,f=1; while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();} return x*f; } bool flag[M]; ll in[N], out[N], f[M]; int head[N], ver[M] ,nxt[M]; ll type, n, m, tot=1, x, y; vector ans; void add(int u,int v) { ver[++tot]=v; nxt[tot]=head[u]; head[u]=tot; } struct ed { int to,nxt; }t[10010<<1]; void dfsearch(int x) { for(int &i=head[x],y; y=ver[i],i; i=nxt[i]) { ll c=(type==1?i/2:i-1); ll sig = i%2; if(flag[c]) continue; flag[c]=1; dfsearch(y); if(type==1) ans.push_back(sig?-c:c); else ans.push_back(c); } } int main () { type = read(); n = read(); m = read(); for(int i=1; i<=m; i++) { x = read(); y = read(); add(x,y); if(type==1) add(y,x); out[x]++; in[y]++; } if(type==1) { for(int i=1; i<=n; i++) if((in[i]+out[i])%2) { printf("NOn"); return 0; } } else { for(int i=1; i<=n; i++) if(in[i]!=out[i]) { printf("NOn"); return 0; } } for(int i=1; i<=n; i++) if(head[i]) { dfsearch(i); break; } if(ans.size()!=m) { cout << "NO" << endl; return 0; } cout<<"YES"< =0; i--) printf("%lld ", ans[i]); puts(""); return 0; }
#pragma comment(linker, "/STACK:102400000,102400000")//手动开大栈区 #includeusing namespace std; int const N=4e5+10; int n,m,cnt,h[N],st[N<<1],top,in[N],out[N],vis[N<<1],f[N],us[N<<1],num[N]; vector a[N],c[N],b[N]; void dfs(int x,int lm){ while (b[x].size()){ int y=b[x][b[x].size()-1]; int t=c[x][b[x].size()-1]; b[x].pop_back(); c[x].pop_back(); if(y =1;i--) printf("%d ",st[i]); } return 0; }



