hiho一下 第五十周 (求欧拉路径)
http://hihocoder.com/contest/hiho50/problem/1
这题有重边,所以邻接矩阵用来统计节点u,v之间有多少条边相连,并且用另外一个数组统计每个节点的入度.
然后查找一个入度为奇数的点进行dfs(如果不存在就从n开始),
dfs的时候每次经过一条边就把这条边删除,因为一条边不会经过两次。
递归的时候保存路径.
总结起来:求解欧拉回路的方法就是,使用dfs,如果某条边被搜索到,则删除这条边,每次dfs结束之后,看当前节点还有没有与之相连的边,有就继续dfs下去.
最后,记录的回溯路径就是欧拉回路.
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 using namespace std; 5 int p[10005],in[1005]; 6 int n,m,j; 7 int g[1005][1005]; 8 void dfs(int x) 9 { 10 //printf("%d\n",x); 11 for(int i=1;i<=n;i++) 12 { 13 if(g[x][i]) 14 { 15 //printf("%d\n",g[x][i]); 16 int u=g[x][i]; 17 g[x][i]--; 18 g[i][x]--; 19 dfs(i); // 20 } 21 } 22 p[j++]=x; 23 } 24 int main() 25 { 26 //freopen("a.txt","r",stdin); 27 int a,b,k; 28 while(~scanf("%d%d",&n,&m)) 29 { 30 memset(g,0,sizeof(g)); 31 memset(in,0,sizeof(in)); 32 for(int i=0;i<m;i++) 33 { 34 scanf("%d%d",&a,&b); 35 in[a]++; 36 in[b]++; 37 g[a][b]++; 38 g[b][a]++; 39 } 40 memset(p,0,sizeof(p)); 41 j=1; 42 for(int i=1;i<=n;i++) 43 if(in[i]&1) 44 { 45 k=i; 46 break; 47 } 48 // printf("%d\n",j); 49 if(k<=n) dfs(k); 50 else dfs(n); 51 for(int i=1;i<j-1;i++) 52 printf("%d ",p[i]); 53 printf("%d\n",p[j-1]); 54 } 55 return 0; 56 }
从别人看到了输入挂:
1 #include <cstdio> 2 int g[1001][1001]={0},path[5002]={0},N,M,u,v,i,pathsize=0,start,deg[1001]={0}; 3 char ch; 4 void read(int &aa) 5 { 6 aa=0; 7 while(ch=getchar(),(ch<'0'||ch>'9')&&(ch!='-')); 8 while(ch>='0'&&ch<='9') {aa=(aa<<3)+(aa<<1)+ch-'0';ch=getchar();} 9 } 10 void dfs(int b) 11 { 12 for(int i=1;i<=N;++i) { 13 if(i!=b&&g[b][i]) { 14 --g[b][i],--g[i][b]; 15 dfs(i); 16 } 17 } 18 ++pathsize; 19 path[pathsize]=b; 20 } 21 int main() 22 { 23 read(N),read(M); 24 for(;M--;) { 25 read(u),read(v); 26 ++g[u][v],++g[v][u]; 27 ++deg[u],++deg[v]; 28 } 29 for(start=1;start<=N;++start) 30 if(deg[start]&1) 31 break; 32 if(start<=N) 33 dfs(start); 34 else 35 dfs(N); 36 for(i=1;path[i];++i) printf("%d ",path[i]); 37 }