1、def:从图上一点出发,经过所有边且只能一次,最终能回到起点的回路。
2、满足条件
(1)连通,即无孤立点。
(2)对无向图:奇点个数为0;对有向图:每个点的入度等于出度。
3、变形:一笔画问题
(1)连通
(2)无向图:奇点个数为0或2,且为2的时候这两个顶一定是起点和终点;有向图:存在两个顶点,入度不等于出度。
练习:NYOJ42
#include
#include
#include
using namespace std;
struct node
{
int to;
int next;
}edge[2010*2];
int vis[1010];
int degeree[1010];
int head[2010];
/**确定无向图是否连通,如果所有点都被访问则说明无孤立点,即连通**/
void dfs(int x)
{
vis[x] = 1;
int i;
for(i = head[x]; i != -1; i = edge[i].next)
{
if(!vis[edge[i].to])
dfs(edge[i].to);
}
}
int visit[2*2010];
int ans[2010];
int ansi;
/*******如果存在欧拉回路,记录欧拉回路*********/
void DFS(int x)
{
int k;
for(k = head[x]; k != -1; k = edge[k].next)
{
if(!visit[k])
{
visit[k] = true;
visit[k^1] = true;
DFS(edge[k].to);
ans[ansi] = k; //保存边
cout<
<<" ";//已经遍历的点
ansi++;
}
}
}
int main()
{
int t;
int n,m;
int i,a,b,num;
scanf("%d",&t);
while(t--)
{
memset(degeree,0,sizeof(degeree));
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
{
/***注意链式前向星存储无向图的时候每条边要存储两次***/
for(i = 1; i <= m*2; i+=2)
{
scanf("%d%d",&a,&b);
edge[i].to = b;
edge[i].next = head[a];
edge[i^1].to = a;
edge[i^1].next = head[b];
head[b] = i^1;
head[a] = i;
degeree[a]++;
degeree[b]++;
}
}
dfs(1);
int flag = 1;
num = 0;
for(i = 1; i <= n; i++)
{
if(vis[i] == 0)
{
flag = 0;
break;
}
if(degeree[i] % 2 == 1)
num++;
}
if(flag == 0)//图是不连通的
{
printf("No\n");
}
else
{
if(num == 2 || num == 0)
//对于无向图,如果度为奇数的点为0或者为2且这两个点为起点和终点,那么存在欧拉回路
{
printf("Yes\n");
//ansi = 0;
//DFS(1);
//cout<