欧拉回路--模板

概念:

  1. 欧拉回路 :图\(G\)中经过每条边一次并且仅一次的回路称作欧拉回路

  2. 欧拉路径: 图\(G\)中经过每条边一次并且仅一次的路径称作欧拉路径

  3. 欧拉图: 存在欧拉回路的图称为欧拉图

  4. 半欧拉图: 存在欧拉路径但不存在欧拉回路的图称为半欧拉图

性质与定理:

  1. 无向图\(G\)为欧拉图,当且仅当\(G\)为连通图且所有顶点的度为偶数

  2. 无向图\(G\)为半欧拉图,当且仅当\(G\)为连通图且除了两个顶点的度为奇数之外,其它所有顶点的度为偶数

  3. 有向图\(G\)为欧拉图,当且仅当\(G\)的基图连通,且所有顶点的入度等于出度

  4. 有向图\(G\)为半欧拉图,当且仅当\(G\)的基图连通,且存在顶点\(u\)的入度比出度大1,\(v\)的入度比出度小1,其它所有顶点的入度等于出度

其他性质定理不想在这里一一陈列了,反正我也不会……

code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int read(){
	int x = 1,a = 0;char ch = getchar();
	while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
	while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
	return x*a;
}
const int maxn = 1e6+10;
int t,n,m;
vector<int> g;
struct node{
	int to,nxt;
}ed[maxn*2];
int head[maxn*2],tot = 1;
void add(int u,int to){
	ed[++tot].to = to;
	ed[tot].nxt = head[u];
	head[u] = tot;
}
int flag[maxn];
void dfs(int x){
	for (int &i = head[x];i;i = ed[i].nxt){
		int to = ed[i].to,num;
		if (t == 1) num = i/2;
		else num = i-1;
		bool op = i&1;
		if (flag[num]) continue;
		flag[num] = 1;
		dfs(to);
		if (t == 1) g.push_back(op?-num:num);
		else g.push_back(num);
	}
}
int in[maxn],out[maxn];
int main(){
	t = read();
	n = read(),m = read();
	for (int i = 1;i <= m;i++){
		int x = read(),y = read();
		add(x,y);
		in[y]++,out[x]++;
		if (t == 1) add(y,x);
	}
	if (t == 1){
		for (int i = 1;i <= n;i++){
			if ((out[i]+in[i])&1){printf("NO\n");return 0;}
		}
	}
	else{
		for (int i = 1;i <= n;i++){
			if (in[i] != out[i]){printf("NO\n");return 0;}
		}
	}
	for (int i = 1;i <= n;i++){
		if (head[i]){
			dfs(i);break;
		}
	}
	if (g.size() != m){printf("NO\n");return 0;}
	printf("YES\n");
	for(int i = m-1;i >= 0;i--) printf("%d ",g[i]);
	puts("");
	return 0;
}
上一篇:DFS序--树链剖分的前置知识


下一篇:UVA1078 Steam Roller