了解了欧拉回路和欧拉道路的性质 :
欧拉道路 最多只有两个奇点(不可能只有一个奇点) 并且当有两个奇点的时候 一个奇点入比出多一 一个奇点出比入多一
采用并查集查看是否连同 如果连通块大于等于2 显然不成立
然后判断 入数组 和出数组的个数 当处于个数不相同的时候说明有奇点 判断此时一个为入奇点 一个为出奇点!!
十分巧妙
根据查找连通性不同 有两种方式:
并查集
#include<bits/stdc++.h> using namespace std; int f[26]; int vis[26]; int in[26]; int out[26]; int find1(int x) { return f[x]==x?x:f[x]=find1( f[x] ); } void uni(int a,int b) { if(find1(a)!=find1(b)) { f[a]=b; } } char m1[1000][1000]; char m2[1000][2]; int main() { int cas;cin>>cas; while(cas--) { int n;cin>>n; memset(vis,0,sizeof(vis)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=0;i<26;i++) f[i]=i; string s;getchar(); while(n--) { getline(cin,s); in[s[0]-'a' ]++; out[s[s.size()-1]-'a' ]++; vis[ s[0]-'a' ]=vis[ s[s.size()-1]-'a' ]=1; uni( f[s[0]-'a'],f[s[s.size()-1]-'a' ]); } int cnt=0; for(int i=0;i<26;i++) { if(vis[i]&&f[i]==i)cnt++; } if(cnt>=2){printf("The door cannot be opened. ");continue;} int ru=-1,chu=-1; int ok=1; for(int i=0;i<26;i++) { if(vis[i]&&in[i]!=out[i]) { if(in[i]==out[i]+1&&ru==-1)ru=1; else if(in[i]==out[i]-1&&chu==-1)chu=1; else ok=0; } } if(ok)printf("Ordering is possible. "); else printf("The door cannot be opened. "); } return 0; }
DFS
#include<cstring> #include<iostream> #include<cstdio> #include<cmath> #define MAXN 100 using namespace std; int vis[MAXN],G[MAXN][MAXN],N, T,f[MAXN],rank[MAXN], in[MAXN],out[MAXN]; void dfs(int u){ vis[u] = true; for(int i=0; i<MAXN; ++i){ if(G[u][i] && !vis[i]) dfs(i); } } int main(){ freopen("input.txt","r",stdin); scanf("%d",&T); while(T--){ memset(G, 0, sizeof(G)); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); char str[1005]; scanf("%d",&N); for(int i=0; i<N; ++i){ scanf("%s", str); ++G[str[0]-'a'][str[strlen(str)-1]-'a']; ++out[str[0]-'a']; ++in[str[strlen(str)-1]-'a']; } bool flag=true; int num1=0, num2=0; for(int i=0; i<MAXN; ++i){ if(!flag) break; if(in[i]!=out[i]){ if(in[i]==out[i]+1) { ++num1; } else if(out[i]==in[i]+1) { ++num2; } else {flag=false; break; } } } if(num1 && num2 && num1+num2>2) flag=false; if(flag){ memset(vis, 0, sizeof(vis)); for(int i=0; i<MAXN; ++i) if(out[i]) { dfs(i); break; } bool flag2=true; for(int i=0; i<MAXN; ++i){ if(in[i] && !vis[i]) { flag2=false; break; } if(out[i] && !vis[i]) { flag2=false; break; } } if(flag2) printf("Ordering is possible. "); else printf("The door cannot be opened. "); } else{ printf("The door cannot be opened. "); } } return 0; }