题目链接: hiho一下 第五十周
思路:hiho已经讲的非常好了,我就不插嘴了。
提示:因为建边时同一条边同相反相的编号相近,比如(u-v)正向边u->v标号为0,反向边v->u标号为1,而0或1除以2都等于0,所以无论正反向建边,只要访问过正向反向中的任何一条边都可以用head[u]/2把原边标记为vis=1操作
/************************************************************** Problem:hiho 50 User: youmi Language: C++ Result: Accepted Time:3ms Memory:0MB ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <sstream> #include <cmath> #include <queue> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define pt(a) printf("%d ",a) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; int n,m; const int maxn=1000+10; const int maxm=5000+10; int head[maxn],euler[maxm],vis[maxn],deg[maxm<<1];//因为输出m+1个点,所以euler的大小应该为maxm int tot,T; struct side { int v,next; }e[maxm<<1]; void build(int u,int v) { e[T].v=v; e[T].next=head[u]; head[u]=T++; } void init() { tot=0; T=0; ones(head); zeros(vis); zeros(deg); } void dfs(int u) { //pt(u); while(head[u]!=-1) { int v=e[head[u]].v; if(!vis[head[u]/2]) { vis[head[u]/2]=1;//标记无向边u-v访问过 dfs(v); } head[u]=e[head[u]].next;//删除操作 } euler[++tot]=u;//记录欧拉路径 } int main() { //freopen("in.txt","r",stdin); while(~sc2(n,m)) { init(); int u,v; while(m--) { sc2(u,v); build(u,v); build(v,u); deg[u]++; deg[v]++; } int flag=1; rep1(i,n)//查找度为奇数的点,如果都为偶数,那么随便从哪个点开始dfs都一样 { if(deg[i]%2) { flag=i; break; } } dfs(flag); rep1(i,tot) { printf("%d ",euler[i]); } printf(" ");//其实这句加不加都一样,对输出要求相当宽松 } return 0; }