PAT A1126 Eulerian Path

/*----------------------------------------------------------------------

	PAT A1126 Eulerian Path
	题意:歌斯堡七桥问题所产生欧拉路径,为图论的开端,或者叫一笔画问题,邮局送信问题。
	      顶点度为偶数叫偶点,奇数叫奇点,数学上记得基本上就懂意思。
	      能够不重复的遍历所有的边称为存在欧拉路径;若起点与终点为同一点则称存在欧拉环;两者前提是图的连通量为1(即连通的);
	      若不能不重复的遍历所有的边。 
        题解:用数组记录边(两个点连接),
	      调用深搜(深度优先搜索),计算连通分量,
	      根据奇点数与连通分量,判断是否存在欧拉路径。
-----------------------------------------------------------------------*/
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
//从V顶点开始深搜
void DFS(vector <vector <int>> &Adj, vector <bool> &Vis, int V);
//深搜整个图
int DFS_Traverse(vector <vector <int>> &Adj, vector <bool> &Vis);

int main()
{
#ifdef _DEBUG
	ifstream cin("Input.txt");
	ofstream cout("Output.txt");
#endif // _DEBUG

	int Vertices_Num, Edges;//顶点数,边数
	cin >> Vertices_Num >> Edges;
	//刚学的模板初始化
	vector <vector <int>> Adjacent(Vertices_Num + 1);//初始化数组大小或可以用(vector).resize(int n);
	vector <bool> Visited(Vertices_Num + 1, false);//初始化false
	//建立边(顶点的关系)
	int Vertice_1, Vertice_2;//一条边的两个顶点
	for (int i = 1; i <= Edges; ++i)
	{
		cin >> Vertice_1 >> Vertice_2;
		Adjacent[Vertice_1].push_back(Vertice_2);
		Adjacent[Vertice_2].push_back(Vertice_1);
	}
	//统计奇点数
	int Cout_OddDegree = 0;
	for (int i = 1; i <= Vertices_Num; ++i)
	{
		//输出度
		cout << Adjacent[i].size();
		if (i != Vertices_Num)
			cout << ' ';
		else
			cout << endl;
		
		if (Adjacent[i].size() % 2 == 1)
			++Cout_OddDegree;
	}
	//连通分量值
	int Connected_Component = DFS_Traverse(Adjacent, Visited);

	if (Cout_OddDegree == 0 && Connected_Component == 1)//连通且都为偶点
		cout << "Eulerian";
	else if (Cout_OddDegree == 2 && Connected_Component == 1)//连通且但奇点为2(奇点数一定为偶数)
		cout << "Semi-Eulerian";
	else                                                //其余情况
		cout << "Non-Eulerian"; 

#ifdef _DEBUG
	cin.close();
	cout.close();
#endif // _DEBUG

	return 0;
}
//少使用全局变量,采用引用传递省空间
int DFS_Traverse(vector <vector <int>> &Adj, vector <bool> &Vis)
{
	int Connected_Component = 0;
	for (int i = 1; i < Vis.size(); ++i)//若有点为遍历则从该顶点开始深搜
		if (!Vis[i])                    //顶点序号从1开始,i初始化为1
		{
			++Connected_Component;//计算连通分量
			DFS(Adj, Vis, i);
		}
	return Connected_Component;
}

void DFS(vector <vector <int>> &Adj, vector <bool> &Vis, int V)
{
	Vis[V] = true;
	for (int i = 0; i < Adj[V].size(); ++i)//深度优先的关键部分
		if (!Vis[Adj[V][i]])               //区别于广度优先的部分
			DFS(Adj, Vis, Adj[V][i]);
}
//也可用邻接矩阵,比较方便,未试过,应该不会超内存。
为什么没有(preview)预览?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值