欧拉回路三水题 POJ 1041 POJ 2230 POJ 1386
POJ 1386 判断有向图中是否存在欧拉回路
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define maxn 30 5 using namespace std; 6 int fa[maxn],used[maxn],in[maxn],out[maxn]; 7 int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);} 8 void Union(int a,int b){ 9 int x = find(a); 10 int y = find(b); 11 if(x != y) fa[y] = x; 12 } 13 int main() 14 { 15 int kase,n; 16 char str[1005]; 17 scanf("%d",&kase); 18 while(kase--){ 19 scanf("%d",&n); 20 for(int i = 0;i < 26;i++) fa[i] = i; 21 memset(used,0,sizeof(used)); 22 memset(in,0,sizeof(in)); 23 memset(out,0,sizeof(out)); 24 for(int i = 0;i < n;i++){ 25 scanf("%s",str); 26 int len = strlen(str); 27 int a = str[0] - 'a'; 28 int b = str[len-1] - 'a'; 29 out[a]++;in[b]++; 30 used[a] = used[b] = 1; 31 Union(a,b); 32 } 33 int start = 0,end = 0,check = 0; 34 bool flag = 1; 35 for(int i = 0;i < 26;i++) 36 if(fa[i] == i && used[i]) check++; 37 if(check > 1){ 38 printf("The door cannot be opened.\n"); 39 continue; 40 } 41 for(int i = 0;i < 26;i++){ 42 if(in[i] - out[i] == 1) start++; 43 else if(out[i] - in[i] == 1) end++; 44 else if(in[i] - out[i] == 0) continue; 45 else flag = false; 46 } 47 if(!flag) printf("The door cannot be opened.\n"); 48 else if(start <= 1 && end <= 1) printf("Ordering is possible.\n"); 49 else printf("The door cannot be opened.\n"); 50 } 51 return 0; 52 }
POJ 2230 按点输出欧拉回路路径
1 #include <cstdio> 2 #include <cstring> 3 #define maxn 10010 4 #define maxm 100010 5 int v[maxm],next[maxm],vis[maxm]; 6 int first[maxn],e; 7 8 void init(){ 9 e = 0; 10 memset(first,-1,sizeof(first)); 11 } 12 13 void add_edge(int a,int b){ 14 v[e] = b;next[e] = first[a];first[a] = e++; 15 } 16 17 void dfs(int u){ 18 for(int i = first[u];i != -1;i = next[i]){ 19 if(!vis[i]){ 20 vis[i] = 1; 21 dfs(v[i]); 22 } 23 } 24 printf("%d\n",u); 25 } 26 27 int main(){ 28 int n,m; 29 scanf("%d%d",&n,&m); 30 init(); 31 for(int i = 1;i <= n;i++) vis[i] = 0; 32 for(int i = 0;i < m;i++){ 33 int a,b; 34 scanf("%d%d",&a,&b); 35 add_edge(a,b);add_edge(b,a); 36 } 37 dfs(1); 38 return 0; 39 }
POJ 1041 按边输出欧拉回路路径
1 #include <cstdio> 2 #include <cstring> 3 #define maxn 2010 4 int map[50][maxn],degree[50]; 5 int stack[maxn],top; 6 bool vis[maxn]; 7 int m; 8 9 inline int max(int a,int b){ 10 return a > b ? a : b; 11 } 12 void euler(int u){ 13 for(int i = 1;i <= m;i++){ 14 if(map[u][i] && !vis[i]){ 15 vis[i] = 1; 16 euler(map[u][i]); 17 stack[top++] = i; 18 } 19 } 20 } 21 22 int main(){ 23 int x,y,z; 24 while(scanf("%d%d",&x,&y)){ 25 if(!x && !y) break; 26 memset(map,0,sizeof(map)); 27 memset(vis,0,sizeof(vis)); 28 memset(degree,0,sizeof(degree)); 29 top = m = 0; 30 scanf("%d",&z); 31 degree[x]++;degree[y]++; 32 map[x][z] = y;map[y][z] = x; 33 m = max(m,z); 34 while(scanf("%d%d",&x,&y)){ 35 if(!x && !y) break; 36 scanf("%d",&z); 37 degree[x]++;degree[y]++; 38 map[x][z] = y;map[y][z] = x; 39 m = max(m,z); 40 } 41 bool flag = false; 42 for(int i = 1;i < 50;i++){ 43 if(degree[i]&1){ 44 flag = true; 45 break; 46 } 47 } 48 if(flag){ 49 printf("Round trip does not exist.\n"); 50 continue; 51 } 52 euler(1); 53 for(int i = top-1;i >= 0;i--){ 54 if(!flag){ 55 printf("%d",stack[i]); 56 flag = true; 57 } 58 else printf(" %d",stack[i]); 59 } 60 printf("\n"); 61 } 62 return 0; 63 }