1184. 欧拉回路(欧拉回路,模板题)

活动 - AcWing

给定一张图,请你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。

输入格式

第一行包含一个整数 t,t∈{1,2},如果 t=1,表示所给图为无向图,如果 t=2,表示所给图为有向图。

第二行包含两个整数 n,m,表示图的结点数和边数。

接下来 m 行中,第 i 行两个整数 vi,ui,表示第 i 条边(从 11 开始编号)。

  • 如果 t=1 则表示 vi 到 ui 有一条无向边。
  • 如果 t=2 则表示 vi 到 ui 有一条有向边。

图中可能有重边也可能有自环。

点的编号从 1 到 n。

输出格式

如果无法一笔画出欧拉回路,则输出一行:NO。

否则,输出一行:YES,接下来一行输出 任意一组 合法方案即可。

  • 如果 t=1,输出 m 个整数 p1,p2,…,pm。令 e=|pi|,那么 e 表示经过的第 i 条边的编号。如果 pi 为正数表示从 ve 走到 ue,否则表示从 ue 走到 ve。
  • 如果 t=2,输出 m 个整数 p1,p2,…,pm。其中 pi 表示经过的第 i 条边的编号。
数据范围

1≤n≤105
0≤m≤2×105

输入样例1:
1
3 3
1 2
2 3
1 3
输出样例1:
YES
1 2 -3
输入样例2:
2
5 6
2 3
2 5
3 4
1 2
4 2
5 1
输出样例2:
YES
4 1 3 5 2 6

解析: 

一、在无向图中(所有边都是连通的): 

(1)存在欧拉路径的充分必要条件:度数为奇数的点只能有0或2。 

(2)存在欧拉回路(起点和终点相同)的充分必要条件:度数为奇数的点只能有0个。 

二、在有向图中(所有边都是连通的): 

(1)存在欧拉路径的充分必要条件:要么所有点的入度均等于入度;要么除了两个点之外,其余所有的点的出度等于入度,剩余的两个点:一个满足出度比入度多1(起点),另一个满足入度比出度多1(终点)。 

(2)存在欧拉回路(起点和终点相同)的充分必要条件:所有点的入度均等于出度。 

欧拉回路的dfs用边来判重,不能用点。 

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 1e5 + 5, M = 4e5 + 5, INF = 0x3f3f3f3f;

int n, m;
int h[N], e[M], ne[M], idx;
int din[N], dout[N];
int ans[M], cnt;
bool used[M];
int type;

void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs(int u) {
	//cout << "_______________________" << u << endl;
	for (int& i = h[u]; i != -1;) {
		if (used[i]) {
			i = ne[i];
			continue;
		}
		int t;
		if (type == 1) {
			t = i / 2 + 1;
			if (i & 1)t = -t;
		}
		else t = i + 1;
		used[i] = 1;
		if (type == 1) {
			used[i ^ 1] = 1;
		}
		int j = e[i];
		i = ne[i];
		dfs(j);
		ans[++cnt] = t;
	}
}

int main() {
	cin >> type;
	cin >> n >> m;
	memset(h, -1, sizeof h);
	for (int i = 1,a,b; i <= m; i++) {
		scanf("%d%d", &a, &b);
		add(a, b);
		if (type == 1)add(b, a);
		din[b]++, dout[a]++;
	}
	if (type == 1) {
		for (int i = 1; i <= n; i++) {
			if (din[i] + dout[i] & 1) {
				cout << "NO" << endl;
				return 0;
			}
		}
	}
	else {
		for (int i = 1; i <= n; i++) {
			if (din[i] != dout[i]) {
				cout << "NO" << endl;
				return 0;
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		if (h[i] != -1) {
			dfs(i);
			break;
		}
	}
	if (cnt < m) {
		cout << "NO" << endl;
		return 0;
	}
	cout << "YES" << endl;
	for (int i = cnt; i; i--) {
		printf("%d ", ans[i]);
	}
	return 0;
}

相关推荐

  1. 1184. 模板

    2024-02-13 03:50:03       40 阅读
  2. C++的算法:道路与

    2024-02-13 03:50:03       10 阅读
  3. [Tricks] 记各类问题

    2024-02-13 03:50:03       34 阅读
  4. ROS

    2024-02-13 03:50:03       36 阅读
  5. 【数论】

    2024-02-13 03:50:03       22 阅读
  6. 公式之美

    2024-02-13 03:50:03       46 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-13 03:50:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-13 03:50:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-13 03:50:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-13 03:50:03       20 阅读

热门阅读

  1. Terraform实战(三)-在AWS上尝试Terraform的Vault Provider

    2024-02-13 03:50:03       29 阅读
  2. 跨站请求伪造 CSRF 漏洞原理以及修复方法

    2024-02-13 03:50:03       35 阅读
  3. Spring Boot整合Elasticsearch实现高效全文搜索

    2024-02-13 03:50:03       34 阅读
  4. 【股票行业统计】 A股概念板块、A股行业分类

    2024-02-13 03:50:03       36 阅读
  5. LeetCode 第384场周赛个人题解

    2024-02-13 03:50:03       40 阅读
  6. php数组

    php数组

    2024-02-13 03:50:03      30 阅读
  7. c++恶魔轮盘制造第1期输赢

    2024-02-13 03:50:03       33 阅读
  8. 【并发编程】ConditionObject

    2024-02-13 03:50:03       35 阅读
  9. 15.实现数组的扁平化

    2024-02-13 03:50:03       30 阅读
  10. mysql底层结构

    2024-02-13 03:50:03       32 阅读