nyoj-42

思路:(1).用搜索或者并查集判断是否连通 (2).用欧拉图判断是否可以一笔走完

并查集

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int father[2222];
int rank[2222];
int degree[2222];
int find(int x)
{
	return x==father[x]?x:find(father[x]);
}
void Union(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y)
		return ;
	if(rank[x]>rank[y])
	{
		father[y]=x;
		rank[x]++;
	}
	else 
	{
		if(rank[x]==rank[y])
			rank[y]++;
		father[x]=y;
	}
}
int main()
{
	int i,t;
	cin>>t;
	while(t--)
	{
		memset(degree,0,sizeof(degree));
		int n,m;
		cin>>n>>m;
		for(i=0;i<=n;++i)
			father[i]=i,rank[i]=0;
		int sum=0,cnt=0;
		while(m--)
		{
			int x,y;
			cin>>x>>y;
			degree[x]++;
			degree[y]++;
		//	x=find(x); 可以去掉这三个,也可以保留
		//	y=find(y);
		//	if(x!=y)
			Union(x,y);
		}
		for(i=1;i<=n;++i)
		{
			if(find(i)==i)
				cnt++;
			if(degree[i]%2==1)
				sum++;
		}
		if((sum==0 || sum==2) && cnt==1)
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
	}
	return 0;
}

  深搜

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int map[2222][2222],v[2222],degree[2222],P,Q;
void dfs(int cur)
{
	int i;
	v[cur]=1;
	for(i=1;i<=P;++i)
		if(map[cur][i])
		{
			degree[cur]++;
			if(!v[i])
				dfs(i);
		}
}
int main()
{
	int i,j,N;
	cin>>N;
	while(N--)
	{
		int A,B,ok=1;
		memset(map,0,sizeof(map));
		memset(v,0,sizeof(v));
		memset(degree,0,sizeof(degree));
		cin>>P>>Q;
		for(i=0;i<Q;++i)
		{
			cin>>A>>B;
			map[A][B]=1;
			map[B][A]=1;
		}
		dfs(1);
		for(i=1;i<=P;++i)
			if(!v[i])
			{
				ok=0;
				break;
			}
		j=0;
		for(i=1;i<=P;++i)
			if(degree[i]%2)
				j+=1;
		if((j==0 || j==2) && ok)
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
	}
	return 0;
}

  

你可能感兴趣的:(nyoj-42)