NYOJ 42-一笔画问题 (欧拉回路+并查集)

首先用并查集判断是否该图是一个连通图,如果不是就直接返回no

在该图为连通图的基础上判断奇点是否为0或者2(这是判断是否有欧拉回路的充要条件)至于为什么自己去找相关证明。

解释:通过图(无向图或有向图)中所有边一次且仅一次行遍图中所有顶点的通路称为欧拉通路,通过图中所有边一次且仅一次行遍所有顶点的回路称为欧拉回路。具有欧拉回路的图称为欧拉图(Euler Graph),具有欧拉通路而无欧拉回路的图称为半欧拉图。

 /*
 qq:1239198605
 ctgu_yyf

        */

#include<iostream>

#include<cstdio>

#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#define long long LL
using namespace std;
int father[2005];


int findfather(int x)
{
int px=father[x];
while(px!=father[px])
{
px=father[px];
}

while(x!=px)//路径压缩 
{
int t=father[x];
father[x]=px;
x=t;
}

return px;
}






int main()
{
int n;
cin>>n;
while(n--)
{
int m1,m2;
int ans=0;
int value[2005]={0};
memset(father,0,sizeof(father));

cin>>m1>>m2;

for(int i=1;i<=m1;i++)
father[i]=i;

int u,v,uu,vv;
for(int i=0;i<m2;i++)
{
cin>>uu>>vv;
value[uu]++;
value[vv]++;
u=findfather(uu);
v=findfather(vv);

if(u!=v)
father[u]=v;
}

u=findfather(u);
for(int i=1;i<=m1;i++)
{

if(value[i]%2!=0)
ans++;
if(findfather(i)!=u)
{
ans=3;
break;
}
}

if(ans==0||ans==2)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;

 } 




return 0;
}

猜你喜欢

转载自www.cnblogs.com/koris-yyf/p/9048276.html