UVa10129 判断有向图中是否存在欧拉回路
2015-07-24 02:20
399 查看
只需要记录每个单词的首尾字母,把每个字母当做图中的点,两个字母出现在一个单词首尾当做一条有向边,这样就成了求图中是否存在欧拉回路,即能遍历图中所有的边而且不重复。
有向图中存在欧拉回路的条件是:底图是连通的,所有点的入度=出度、或者一个点出度=入度+1(开始点),一个点入度=出度+1(结束点)。
无向图中存在欧拉回路的条件是:所有点的边是偶数、有两个点的边是奇数
开始在对图进行dfs的时候,把点的数目当成了n,一直WR。
有向图中存在欧拉回路的条件是:底图是连通的,所有点的入度=出度、或者一个点出度=入度+1(开始点),一个点入度=出度+1(结束点)。
无向图中存在欧拉回路的条件是:所有点的边是偶数、有两个点的边是奇数
开始在对图进行dfs的时候,把点的数目当成了n,一直WR。
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<string> #include<map> #include<set> #include<algorithm> #include<vector> #include<stack> #include<sstream> #define ll long long using namespace std; /**********************************************************/ const int M_NUM_MAX = 100000+10; const int M_INT_MAX = 0x7fffffff; const double M_DBL_MAX = 1.7976931348623158e+308; const double M_DBL_MIN = 2.2250738585072014e-308; int theMap[30][30],inAndOut[30][2]; int vis[30],exist[30]; int n,num; /**********************************************************/ int min_2 (int x,int y) {return x<y?x:y;} int max_2 (int x,int y) {return x>y?x:y;} void dfs (int i) { vis[i]=1;//每遍历一个点都做标记 num++; for (int j=0;j<30;j++) if ((theMap[i][j]>0||theMap[j][i]>0)&&!vis[j])//底图,去掉箭头 dfs (j); } /**********************************************************/ int main() { //freopen ("in.txt","r",stdin); int t; scanf ("%d",&t); while (t--) { memset (vis,0,sizeof (vis)); memset (theMap,0,sizeof (theMap)); memset (inAndOut,0,sizeof (inAndOut)); memset (exist,0,sizeof (exist)); scanf ("%d",&n); char s[1010]; for (int i=0;i<n;i++){ scanf ("%s",s); theMap[s[0]-'a'][s[strlen(s)-1]-'a']++; exist[s[0]-'a']=exist[s[strlen(s)-1]-'a']=1; } int sum=0; for (int i=0;i<30;i++)//判断所有单词首尾中有几个字母,即图中点的个数 if (exist[i]) sum++; bool success=false; for (int i=0;i<30;i++){ num=0; memset (vis,0,sizeof (vis)); dfs(i); if (num==sum)//对图进行dfs,记录遍历点的个数,如果能遍历图中所有的点,说明底图是连通的 break; } if (num==sum){ int a[30]; for (int i=0;i<30;i++) for (int j=0;j<30;j++){//求出所有点的入度和出度 inAndOut[i][0]+=theMap[i][j]; inAndOut[i][1]+=theMap[j][i]; } int x=0; for (int i=0;i<30;i++) if (inAndOut[i][0]!=inAndOut[i][1]) a[x++]=inAndOut[i][0]-inAndOut[i][1]; //printf ("%d\n",x); if (x==0||(x==2&&a[0]*a[1]==-1) )//若所有点入度=出度,或者一个点入度=出度-1,出度=入度-1,说明存在欧拉回路 success=true; } if (success) printf ("Ordering is possible.\n"); else printf ("The door cannot be opened.\n"); } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++ Custom Control控件向父窗体发送对应的消息
- C++中拷贝构造函数的应用详解