欧拉回路

关于欧拉路径 汉密尔顿路径

欧拉路:
如果给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,这条路称为欧拉路;
如果给定无孤立结点图G,若存在一条回路,经过图中每边一次且仅一次,那么该回路称为欧拉回路。
存在欧拉回路的图,称为欧拉图。

一、 对于无向图G,具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点。
且有零个奇数度结点,存在欧拉回路;有两个奇数度结点,存在欧拉路。

判断无向图G是否连通,可以从任意结点出发,进行深度优先遍历,如果可以遍历到所有点,
说明,图G连通,否则,图G不连通。

如HDU 1878 :http://acm.hdu.edu.cn/showproblem.php?pid=1878

#include <iostream>
#include <fstream>
using namespace std;

ifstream fin("in.txt");

#define LEN 1001
bool visited[LEN];
bool arc[LEN][LEN];
int degree[LEN];
int n,m;

void dfs(int v)         //深度优先遍历
{
	visited[v]=true;
	for(int i=1;i<=n;i++)
	{
		if(!visited[i] && arc[v][i])
		{
			dfs(i);
		}
	}
}

bool isConnected()		//查看遍历后结果
{
	for(int i=1;i<=n;i++)
	{
		if(!visited[i]){return false;}
	}
	return true;
}

bool isCircuit()		//通过度数是否为偶数判断欧拉回路
{
	for(int i=1;i<=n;i++)
	{
		if(degree[i]%2){return false;}
	}
	return true;
}

int main()
{
	int i,p,q;
	while(1)
	{
		memset(visited,0,LEN);
		memset(arc,0,sizeof(bool)*LEN*LEN);
		memset(degree,0,sizeof(int)*LEN);
		fin>>n>>m;
		if(n==0)break;
		for(i=0;i<m;i++)
		{
			fin>>p>>q;
			degree[p]++;degree[q]++;
			arc[p][q]=arc[q][p]=true;
		}
		dfs(1);
		if(!isConnected()){cout<<0<<endl;}
		else{
			if(isCircuit())cout<<1<<endl;
			else cout<<0<<endl;
			}
	}
	return 0;
}


输入文件:in.txt

3 3   (顶点数 边数)
1 2   -->
1 3   --> 边的两个顶点
2 3   -->
3 2
1 2
2 3
0


二 、对于有向图G,具有一条单向欧拉路,当且仅当G是连通的,且每个结点入度等于出度,或者,

除两个结点外,每个结点的入度等于出度,而这两个结点满足,一个结点的入度比出度大1,
另一个结点的入度比出度小1。

判断有向图G是否连通,可以某一结点出发,进行深度优先遍历,如果存在一点作为初始结点
可以遍历到所有点,说明,图G连通,否则,图G不连通。

三、混合图(有的边是单向的,有的边是无向的。常被用于比喻城市里的交通网络,有的路是单行道,有的路是双行道。)
找到一个给每条无向的边定向的策略,使得每个顶点的入度等于出度,这样就能转换成上面第二种情况。这就可以转化成一个二部图最大匹配问题


汉密尔顿路 
给定图G,若存在一条路,经过图中每个结点恰好一次,这条路称作汉密尔顿路。
给定图G,若存在一条回路,经过图中每个结点恰好一次,这条回路称作汉密尔顿回路。
具有汉密尔顿回路的图,称作汉密尔顿图。

定理 5.4.3 若图G=<V,E>具有汉密尔顿回路,则对于结点集V的每个非空子集S,均有W(G-S)<=|S|成立。
其中W(G-S)是G-S 的连通分支数,|S|表示集合S的元素数。
定理 5.4.4 设G是具有n个结点的简单图,如果G中每一对结点度数之和大于等于n-1,则在G中存在一条汉密尔顿路。
定理 5.4.5 设G是具有n个结点的简单图,如果G中每一对结点度数之和大于等于n,则在G中存在一条汉密尔顿回路。

你可能感兴趣的:(网络,交通)