uoj 117 欧拉回路

2024-03-02 08:32
文章标签 欧拉 117 uoj 回路

本文主要是介绍uoj 117 欧拉回路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.判断是否为欧拉存在欧拉回路---裸的判断

欧拉回路就是看一笔能不能把途中所有的边跑完没得重复

对于无向边----建立双向边判断每个点的入度是否为2的倍数   1.1

对于有向边---建立单向边判断每个点的入度与出度是否相等   1.2

然后就是看一下是否所有的点是否连接----可以用并查集或者dfs判断,具体看情况来定。 2

判断是否存在欧拉回路,就是同时满足上边的1,2两个条件

HDU 1878代码 并查集 条件1.1+2

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define me(a,b) memset(a,b,sizeof(a))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define max4(a,b,c,d) max(max(a,b),max(c,d))
#define max3(x,y,z) max(max(x,y),max(y,z))
typedef long long ll;
using namespace std;
const int maxn=1005;
int f[maxn],vis[maxn];
int n,m;
void init()
{for(int i=1;i<=n;i++){vis[i]=0;f[i]=i;}
}
int find(int x)
{if(x==f[x]) return x;else return f[x]=find(f[x]);
}
void unionn(int x,int y)
{int fx=find(x);int fy=find(y);if(fx!=fy)f[x]=y;
}
int main()
{int x,y;while(cin>>n,n){cin>>m;init();for(int i=1;i<=m;i++){scanf("%d %d",&x,&y);unionn(x,y);vis[x]++;vis[y]++;}bool flag=true;int cnt=0;for(int i=1;i<=n;i++){if(f[i]==i)cnt++;}if(cnt>1)flag=false;else{for(int i=1;i<=n;i++)if(vis[i]%2==1){flag=false;break;}}if(flag)printf("1\n");elseprintf("0\n");}return 0;
}

2。输出欧拉回路 uoj 117

分两种情况建立单向或者双向边

判断1.1 or 1.2 ,然后用dfs来进行遍历,如果能够遍历所有的边,那么输出即可

但是这道题的数据很大很坑,存在的问题就是可能会出现自环,比如给了10000组的 1 1边,那么dfs的时候遍历是会超时的,利用邻接表的性质进行优化

代码如下

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define me(a,b) memset(a,b,sizeof(a))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define max4(a,b,c,d) max(max(a,b),max(c,d))
#define max3(x,y,z) max(max(x,y),max(y,z))
typedef long long ll;
const double pi=acos(-1.0);
const double E=2.718281828459;
using namespace std;
const int maxn=1e5+5;
const int maxm=2e5+5;
struct node
{int to,p,vis;
}edge[maxm<<1];
int n,m;
int in[maxn],out[maxn];
int head[maxn],sign,cnt;
void add(int u,int v)
{edge[++sign]=node{v,head[u],0};head[u]=sign;
}
void init()
{cnt=sign=0;memset(head,-1,sizeof(head));for(int i=1;i<=n;i++)in[i]=out[i]=0;
}
int ans[maxm];
void dfs_unedge(int u)
{for(int i=head[u];~i;i=head[u])//这里就是优化的地方{head[u]=edge[i].p;//譬如起始点u点连接了10000个点  u->1>2>3>4>5>.........//那么我一下循环到u点的时候,它又要从1,2,3,4,5一个一个判断之前是否走过//而现在当我们从u走到过1这个位置后,head[u]=head[1],那么u->1这条边就不在判断了//也就是说走过一条边这条边下次就不再走了,那么复杂度就是O(m)int v=edge[i].to;if(edge[i].vis)continue;edge[i].vis=1;if(i&1)edge[i+1].vis=1;elseedge[i-1].vis=1;dfs_unedge(v);ans[++cnt]=(i+1)/2;if(i%2==0)ans[cnt]*=-1;}
}
void dfs_diredge(int u)
{for(int i=head[u];~i;i=head[u]){head[u]=edge[i].p;int v=edge[i].to;if(edge[i].vis==0){edge[i].vis=1;dfs_diredge(v);ans[++cnt]=i;}}
}
int main()
{int t,x,y;scanf("%d%d%d",&t,&n,&m);init();for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);add(x,y);if(t==1){add(y,x);in[x]++;in[y]++;}else{out[x]++;in[y]++;}}if(t==1)//条件1.1{for(int i=1;i<=n;i++)if(in[i]&1)return !printf("NO\n");}else//条件1.2{for(int i=1;i<=n;i++)if(in[i]!=out[i])return !printf("NO\n");}if(t==1) dfs_unedge(x);//else dfs_diredge(x);if(cnt!=m)//条件2printf("NO\n");else{printf("YES\n");for(int i=cnt;i>=1;i--)printf("%d ",ans[i]);}return 0;
}

 

这篇关于uoj 117 欧拉回路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/765518

相关文章

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

欧拉系统 kernel 升级、降级

系统版本  cat  /etc/os-release  NAME="openEuler"VERSION="22.03 (LTS-SP1)"ID="openEuler"VERSION_ID="22.03"PRETTY_NAME="openEuler 22.03 (LTS-SP1)"ANSI_COLOR="0;31" 系统初始 kernel 版本 5.10.0-136.12.0.

nyoj99(并查集+欧拉路+dfs)

单词拼接 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串。 前一个单词的结尾应该与下一个单词的道字母相同。 如 aloha dog arachnid gopher tiger rat   可以拼接成:aloha.arachnid.dog.gopher.rat.tiger 输入 第一行是一个整

nyoj42(并查集解决欧拉回路)

一笔画问题 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。 规定,所有的边都只能画一次,不能重复画。   输入 第一行只有一个正整数N(N<=10)表示测试数据的组数。 每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<

UVa 10820 Send a Table (Farey数列欧拉函数求和)

这里先说一下欧拉函数的求法 先说一下筛选素数的方法 void Get_Prime(){ /*筛选素数法*/for(int i = 0; i < N; i++) vis[i] = 1;vis[0] = vis[1] = 0;for(int i = 2; i * i < N; i++)if(vis[i]){for(int j = i * i; j < N; j += i)vis[j] =

JD 1027:欧拉回路

OJ题目:click here~~ 题目分析: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径。若该路径是一个圈,则称为欧拉(Euler)回路。 具有欧拉路径的图称为欧拉图(简称E图)。 无向图存在欧拉回路的充要条件: 一个无向图存在欧拉回路,当且仅当该图拥有奇数度数的顶点的个数为0且该图是连通图。 有向图存在欧拉回路的充要条件: 一

欧拉数据库的搭建及其部署

数据库的搭建 进行数据库安装前,必须保证软件yum仓库搭建完成 使用命令 dnf install mariadb-server,发现冲突selinux-policy-targeted-35.5-21.oe2203sp3.noarch有问题 [root@localhost yum.repos.d]# dnf install mariadb-server [root@localhost yu

欧拉下搭建第三方软件仓库—docker

1.创建新的文件内容 切换目录到etc底下的yum.repos.d目录,创建docker-ce.repo文件 [root@localhost yum.repos.d]# cd /etc/yum.repos.d/ [root@localhost yum.repos.d]# vim docker-ce.repo 编辑文件,使用阿里源镜像源,镜像源在编辑中需要单独复制 https://mirr

【UVa】 10735 Euler Circuit 混合图的欧拉回路 最大流

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1676 题目要求:求混合图的欧拉回路+输出路径。 题目分析: 先看一段比较流行的说法吧~: -----------------------------------------