欧拉图 + 并查集 (虚虚实实)(2021-8-13)

虚虚实实

题意:

算卦先生来问你,对于每个他给出的无向图,是否存在一条路径能够经过所有边恰好一次,并且经过所有点不需要满足最后回到起点。 (欧拉通路+欧拉图)

输入:
第一行一个数 T,表示有 T 组数据。对与每组数据,第一行有两个数 n,m,接下去 m 行每行两个数 u,v 描述一条无向边 (u,v)。图不保证联通。

输出:
对于每组数据,如果存在,输出"Zhen" ,否则输出 “Xun” 。

示例1
输入
2
2 2
1 1
2 1
4 6
1 3
1 4
1 2
3 2
4 2
4 3

输出
Zhen
Xun

备注:
1.1≤T≤200
2.2≤n≤30
1≤m≤ n(n−1)/2

欧拉通图:图中每条边且只通过一次,并且经过每一顶点的通路(首尾不相接)
欧拉图:图中每条边且只通过一次,并且经过每一顶点的回路(首尾相接)

无向图是否具有欧拉通路/回路的判定:

欧拉通路:图联通,图中只有俩个度为奇数的顶点(欧拉通路的俩个端点)
欧拉回路:图联通,图中所有顶点度数均为偶数

此题:
(1)并查集判断图是否连通
(2)图中奇数度数的顶点的个数只能为0或者2个
(3)满足(1)(2)要求即输出Zhen,反之亦然

注意:
自环会让度加2

#include<iostream>
#include<string.h>
using namespace std;
const int maxn=35;
int indegree[maxn];
int outdegree[maxn];
int pre[maxn];
void init(int n){
	for(int i=1;i<=n;i++){
		pre[i]=i;
	}
}
int find(int x){
	return x==pre[x] ? x : pre[x]=find(pre[x]); 
}
int main(){
	int t;
	cin>>t;
	int n,m;
	while(t--){
		cin>>n>>m;
		init(n);
		memset(indegree,0,sizeof(indegree));
		memset(outdegree,0,sizeof(outdegree));
		int u,v;
		while(m--){
			cin>>u>>v;
			indegree[v]++;
			outdegree[u]++;
			int up=find(u);
			int vp=find(v);
			if(up!=vp){
				pre[up]=vp;
			}
		}
		int cnt=0;
		int flag=0;
		for(int i=1;i<=n;i++){
			if(pre[i]==i){
				cnt++;
			}
			if((indegree[i]+outdegree[i])%2!=0){
				flag++;
			}
		}
		if(cnt==1&&(flag==2||flag==0)){
			cout<<"Zhen"<<endl;
		}
		else{
			cout<<"Xun"<<endl; 
		}
	}
	
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值