首先是欧拉回路的判断
在无向图中的欧拉回路 每个顶点的度都是偶数 且图为连通图 在判断连通性的时候可以使用并查集来判断图的连通性 也可以使用dfs或bfs来判断
不过运行速度会慢一点
在有向图中 欧拉回路 每个顶点的入度等于出度 且是连通的 这里的连通指的是弱连通
有向图的强连通性:任意两个顶点 a和b 既有a到b的路径又有b到a的路径
有向图的单向连通性: 任意两个顶点 a和b 至少有a到b或者b到a的路径
有向图的弱连通性 : 是指将有向图转换成无向图后 无向图是连通的
下面是求有向图中的欧拉路径的一个题目
http://poj.org/problem?id=2337
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
const int nmax=27;
const int mmax=1000;
int chudu[nmax];
int rudu[nmax];
int father[nmax];
int vis[mmax];
vector<string > mystring;
struct edge
{
int adjvex;
int adjid;
struct edge *next;
string tmp;
};
struct ver
{
struct edge *first;
};
struct graph
{
struct ver v[nmax];
int mnum;
}mg;
void init()
{
for(int i=0;i<nmax;i++)
{
mg.v[i].first=NULL;
chudu[i]=0;
rudu[i]=0;
father[i]=i;
}
mystring.clear();
memset(vis,0,sizeof(vis));
}
int findfa(int a)
{
if(father[a]==a) return a;
else
{
return father[a]=findfa(father[a]);
}
}
void merge(int a,int b)
{
if(findfa(b)==a)
return;
father[a]=b;
}
bool judge(int &start)//判断是否有欧拉路径或者回路 如果有求出出发点
{
bool flag=false;//第一个根是否找到的标志
bool churu=false;
bool ruchu=false;
int fa;
int num=0;
for(int i=0;i<nmax;i++)//检查有向图的弱连通性
{
if(rudu[i]||chudu[i])//输入中是否输入了这个顶点
{
if(!flag)
{
fa=findfa(i);//存储根节点
flag=true;//找到第一个根
}
else
{
if(fa!=findfa(i))
return false;
}
start=i;//如果是环则随便一个顶点作为出发点
}
}
for(int i=0;i<nmax;i++)//检查入度和出度的关系
{
if(rudu[i]!=chudu[i]) num++;//记录出度不等于入度的顶点的个数
if(chudu[i]-rudu[i]==1)
{
start=i;
churu=true;
}
if(rudu[i]-chudu[i]==1)
{
ruchu=true;
}
}
if((ruchu&&churu&&num==2)||num==0)//如果只有两个点入度和出度不等 且一个入度比出度大一 一个出度比入度大一或者出度等于入度
return true;
else
return false;
}
void dfs(int s)
{
struct edge *temp;
int id;
for(temp=mg.v[s].first;temp;temp=temp->next)//如果有指向自己的边 优先访问自己
{
if(temp->adjvex==s)
{
id=temp->adjid;
if(!vis[id])
{
vis[id]=1;
mystring.push_back(temp->tmp);
//cout<<temp->tmp<<".";
dfs(temp->adjvex);
}
}
}
for(temp=mg.v[s].first;temp;temp=temp->next)
{
id=temp->adjid;
if(!vis[id])
{
vis[id]=1;
mystring.push_back(temp->tmp);
//cout<<temp->tmp<<".";
dfs(temp->adjvex);
}
}
}
int main(int argc,char *argv[])
{
int n;
cin>>n;
while(n--)
{
int a,b,start;
string s;
cin>>mg.mnum;
init();//初始化图的连接表
getchar();
for(int i=1;i<=mg.mnum;i++)
{
getline(cin,s);
a=s[0]-'a';
b=s[s.length()-1]-'a';
struct edge *temp=new edge;
temp->adjvex=b;
temp->tmp=s;
temp->next=mg.v[a].first;
mg.v[a].first=temp;
temp->adjid=i;
chudu[a]++;
rudu[b]++;
merge(a,b);
}
if(!judge(start))
{
cout<<"***"<<endl;
}
else
{
dfs(start);
for(int i=0;i<mystring.size();i++)
{
if(i==mystring.size()-1)
cout<<mystring[i]<<endl;
else
cout<<mystring[i]<<".";
}
mystring.clear();
}
}
return 1;
}