链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=42
这道题我刚开始用的dfs,结果出了点小问题~~~结果时对时不对。。。
网上说可以用欧拉回路解决,这就只需要解决两个问题了。判断图是否连通,依次判断图中每个点的出度
判断连通可以用dfs,也可以用并查集。 dfs遍历该图,并标记所访问的结点,遍历结束,若存在没标记的点,则不是连通。
并查集第一步把每个元素初始化为单集合,其集合名字为其本身,也就是father数组,往集合添加元素时,首先利用father数组查到所在集合的名字和该集合拥有的元素(小集合并到大集合中)
dfsAC的代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int Edge[2001][2001],visited[1001],degree[4005];
void dfs(int cur,int v)
{
visited[cur]=1;
int i;
for(i=1;i<=v;i++)
if(Edge[cur][i]) //从邻接顶点往下寻找并计算出结点的度
{
degree[cur]++;
if(!visited[i]) //标记邻接顶点
dfs(i,v);
}
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
int v,e;
memset(Edge,0,sizeof(Edge));
memset(visited,0,sizeof(visited));
memset(degree,0,sizeof(degree));
scanf("%d%d",&v,&e);
int j,x,y,ok=1;
for(j=1;j<=e;++j)
{
scanf("%d%d",&x,&y);
Edge[x][y]=Edge[y][x]=1;
}
dfs(1,v);
for(j=1;j<=v;++j) //循环判断图是否连通
{
if(visited[j]==0)
{
ok=0;
break;
}
}
if(!ok) printf("No\n");
else
{
j=0;
for(int k=1;k<=v;++k)
if(degree[k]%2!=0)
j+=1;
if(j==2||j==0) //j=2时,则有两个点必为起点和终点,j=0,则任意点为起始点
printf("Yes\n");
else
printf("No\n");
}
}
}