首页 > 其他分享 >欧拉路径

欧拉路径

时间:2024-07-26 18:41:25浏览次数:6  
标签:head return int 路径 cnt edge outn 欧拉

欧拉路径

定义

欧拉路径,指在有向图 $G$ 中,可以从起点 $v_1$​ 开始,经过每条边,则此路径为欧拉路径。

欧拉回路,就是在欧拉路径的基础上,限定终点也必须为 $v_1$。

判定方法

欧拉回路,其实就是一笔画问题。而根据我们的小学数学可知,如果一个图可以一笔画,则必须满足以下条件之一:

  • 有两个节点连边个数为奇数
  • 全部节点连边个数为偶数

针对第一条件,则起点就为其中一个奇点,终点为另一个奇点。

第二条件,则起点设在哪里都行,终点也为起点,默认为编号最小的节点。

生成路径

采取 dfs,每次遍历到一个节点,都将其进栈。最后倒序输出即为欧拉路径。

每遍历到一个节点,都需要判断与其的连边是否已经遍历过,没遍历过则继续遍历指向节点。

朴素代码:

//e[i]:链式前向星
// vis:每条边是否遍历过
void dfs(int u)
{
	for(int i=head[u];i;i=e[i].to)//剪枝优化
	{
		if(vis[i]) continue;
         vis[i]=true;
		dfs(edge[i].to);
	}
	st.push(u);
	return;
}

例题:P7771 【模板】欧拉路径

朴素版代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=2e5+5;
int n,m;
int start=1,inn,outn;
bool vis[M];
struct EDGE{
	int from,to,pre;
}e[M],edge[M];
int head[N],u,v,cnt_edge;
int in[N],out[N];
void add(int from,int to)
{
	edge[++cnt_edge].from=from;
	edge[cnt_edge].to=to;
	edge[cnt_edge].pre=head[from];
	head[from]=cnt_edge;
	return;
}
stack<int> st;
void dfs(int u)
{
	for(int i=head[u];i;i=e[i].to)
	{
		if(vis[i]) continue;
         vis[i]=true;
		dfs(edge[i].to);
	}
	st.push(u);
	return;
}
bool cmp(EDGE a,EDGE b)//简简单单排个序
{
	if(a.from!=b.from)
		return a.from<b.from;
	return a.to>b.to;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&e[i].from,&e[i].to);
		in[e[i].to]++;out[e[i].from]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(abs(in[i]-out[i])>1)//出度与入度差>1,直接排除
		{
			printf("No\n");
			return 0;
		}
		if(in[i]-out[i]==1)//入度比出度多一,为终点
			inn++;//有多少个可以为终点
		if(out[i]-in[i]==1)//起点,并标记
		{
			outn++;//有多少个可以为起点
			start=i;
		}
	}
	if((inn==0&&outn==0)||(inn==1&&outn==1))//上文所述的两种判定方法
	{
		sort(e+1,e+m+1,cmp);
		for(int i=1;i<=m;i++)
			add(e[i].from,e[i].to);
		dfs(start);
		while(!st.empty())
		{
			printf("%d ",st.top());
			st.pop();
		}
	}
	else
		printf("No");
	putchar('\n');
	return 0;
}

然而,实测只有 $90pts$,原因是 dfs 中的遍历没有剪枝,浪费时间。

优化办法:遍历时直接更新 head 数组,免得每次都得遍历 $m$ 次。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=2e5+5;
int n,m;
int start=1,inn,outn;
bool vis[M];
struct EDGE{
	int from,to,pre;
}e[M],edge[M];
int head[N],u,v,cnt_edge;
int in[N],out[N];
void add(int from,int to)
{
	edge[++cnt_edge].from=from;
	edge[cnt_edge].to=to;
	edge[cnt_edge].pre=head[from];
	head[from]=cnt_edge;
	return;
}
stack<int> st;
void dfs(int u)
{
	for(int i=head[u];i;i=head[u])
	{
		head[u]=edge[i].pre;
		dfs(edge[i].to);
	}
	st.push(u);
	return;
}
bool cmp(EDGE a,EDGE b)
{
	if(a.from!=b.from)
		return a.from<b.from;
	return a.to>b.to;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&e[i].from,&e[i].to);
		in[e[i].to]++;out[e[i].from]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(abs(in[i]-out[i])>1)
		{
			printf("No\n");
			return 0;
		}
		if(in[i]-out[i]==1)
			inn++;
		if(out[i]-in[i]==1)
		{
			outn++;
			start=i;
		}
	}
	if((inn==0&&outn==0)||(inn==1&&outn==1))
	{
		sort(e+1,e+m+1,cmp);
		for(int i=1;i<=m;i++)
			add(e[i].from,e[i].to);
		dfs(start);
		while(!st.empty())
		{
			printf("%d ",st.top());
			st.pop();
		}
	}
	else
		printf("No");
	putchar('\n');
	return 0;
}

标签:head,return,int,路径,cnt,edge,outn,欧拉
From: https://www.cnblogs.com/Atserckcn/p/18326020

相关文章

  • 【MATLAB源码-第159期】基于matlab的胡桃夹子优化算法(NOA)机器人栅格路径规划,输出做短
    操作环境:MATLAB2022a1、算法描述胡桃夹子优化算法(NutcrackerOptimizationAlgorithm,NOA)是一个灵感来源于胡桃夹子的故事的元启发式优化算法。这个故事中,胡桃夹子是一个能够将坚果壳轻易地破开以获取内部果仁的工具。在优化算法的语境下,这个过程被比喻为寻找问题解决方案......
  • .url 文件通常是指Windows操作系统中的一种快捷方式文件,用于创建指向网络资源或本地文
    .url文件通常是指Windows操作系统中的一种快捷方式文件,用于创建指向网络资源或本地文件系统路径的链接。这种文件类型实际上是文本文件,其内容格式类似于INI文件,包含了一个URL或者本地文件路径。主要特点和用途:创建快捷方式:.url 文件允许用户创建指向特定网页、FTP站点或本......
  • 如何将相对路径设置为解释器路径 xlwings 自定义加载项
    我使用xlwings制作了自定义加载项。我有一本字典,其中:phodnota.py、phodnota.xlam和Python311(带有python解释器和所有需要的库的字典)。问题是,当我尝试添加到解释器路径相对路径Python311\python.exe时,它​​不起作用。我不断收到错误。我找不到......
  • 洛谷 模板 单源最短路径(标准版)
    原题p4779题目背景2018年7月19日,某位同学在 NOIDay1T1归程 一题里非常熟练地使用了一个广为人知的算法求最短路。然后呢?100→60;Ag→Cu;最终,他因此没能与理想的大学达成契约。小F衷心祝愿大家不再重蹈覆辙。题目描述给定一个 n 个点,m 条有向边的带非负......
  • Android开发 - Canvas中Path路径的详解与使用
    Path回顾Path类封装复合(多轮廓)几何路径由直线段、二次曲线和三次曲线组成。它可以用画布绘制:canvas.drawPath(path,paint),填充或笔划(基于绘画的样式),或者可以用于剪裁或绘制路径上的文本。Path既是路径,路径走多了就变成一种套路,只要我们会解套,那这种套路就是高速公路。路径走完形......
  • Qt/C++使用小记1【.exe程序拖拽文件使程序启动时,获取该文件路径】
    写一写小小的收获吧,因为踏足也有一定时间了,自己也平时有记录,但是总感觉文件转来转去很麻烦,有时甚至找不到,就放在网上,自己需要的时候也可以翻一翻~第一个小收获:众所周知,qt生成的默认的.exe也是支持拖拽文件到.exe图标上的时候打开程序的,但是程序内不会有任何表现,仅仅是启动程......
  • AcWing873. 欧拉函数
    题目链接:https://www.acwing.com/problem/content/description/875/题目叙述:给定n个正整数ai,请你求出每个数的欧拉函数。欧拉函数的定义:1∼N中与N互质的数的个数被称为欧拉函数,记为ϕ(N)。输入格式第一行包含整数n。接下来n行,每行包含一个正整数ai。输出格式输出共......
  • 图的最短路径算法(SPFA,Dijkstra,Bellman_Ford)(迪杰斯特拉算法,Spfa算法,贝尔曼-福特算
    目录Dijkstra迪杰斯特拉算法写法时间复杂度例题描述输入描述输出描述样例输入用例输出用例写法Spfa算法例题描述输入描述输出描述样例输入用例输出用例写法Bellman_Ford算法(贝尔曼-福特算法)写法例题描述输入描述输出描述样例输入样例输出样例......
  • 使用 pyinstaller / auto py 执行时如何处理相对资源路径?
    我有python脚本,可将日志文件和另一个csv保存到相对资源路径。pyinstaller抛出文件未找到错误。代码的文件结构是。-ProjectFolder|-common||-commom.py|-src||-main.py||-anotherclass.py|-resources||-output.logs||-result.csv输出exe目......
  • 代码随想录 day34 不同路径 | 不同路径 II
    不同路径不同路径解题思路通过动态规划,先将第一行和第一列设为1,目的是初始化dp,这样设置的理由是这些格子只有一条路能达到,接着就是遍历整个路径,每个格子所包含的路径和为其左边和上边的路径数之和,随后在目的地格子得到值。知识点动态规划心得没想到初始化的方式,导致没有实......