歐拉圖和哈密頓圖

歐拉圖

歐拉圖:具有歐拉回路的圖叫做歐拉圖
歐拉回路:從起點出發,每條邊有且只經過一次,最終回到起點的路徑
歐拉通路:從起點出發,每條邊有且只經過一次,不要求回到其點的迴路

半歐拉圖,擁有歐拉通路,但不用有歐拉回路的圖叫做半歐拉圖

判斷方法

在這裏插入圖片描述此外判斷一個圖是否立連通可已使用並查集
在這裏插入圖片描述
求歐拉回路的方法

const int maxn=1e3;
int mp[maxn][maxn],ans[maxn];
int cnt=0;

void dfs(u)
{
	for(int i=1;i<=n;i++)
	{
		if(mp[u][i]!=0)
		{
			int t=mp[u][i];
			mp[u][i]=0;
			dfs(v);
			ans[cnt++]=t;
		}
	}
}

一位學姐的代碼
在這裏插入圖片描述對於fluery算法求歐拉回路,我自己還不會,太菜了

哈密頓圖

在這裏插入圖片描述
Dirac定理: 無向圖,有 N 個節點,若所有節點的度數都大於等於 N/2,則哈密頓迴路一定存在。注意,“N/2” 中的除法不是整除,而是實數除法。如果 N 是偶數,當然沒有歧義;如果 N 是奇數,則該條件中的 “N/2” 等價於 “⌈N/2⌉”

競賽圖:有向圖,每對頂點之間都有一條邊相連的有向圖稱爲競賽圖

在dirac定理的前提下求哈密頓迴路

const int maxn=1e3;
int mp[maxn][maxn],ans[maxn],vis[maxn];
int cnt=0;
int n;//n個點 
int s,t;//哈密頓圖的起點和終點 

void expand() 
{
	while(1)
	{
		int flag=0;
		for(int i=1;i<=n;i++)
		{
			if(!vis[i]&&mp[t][i])
			{
				ans[cnt++]=i;
				t=i;
				flag=1;
				break;
				vis[i]=1;
			}
		}
		if(flag==0)
		{
			break;
		}		
	}	
} 

void _reverse(int l,int r)
{
	for(int i=0;i<(r-l+1)/2;i++)
	{
		swap(ans[l+i],ans[r-i]);
	}	
}

void hamidun(int start)
{	
	s=start;
	vis[s]=1;
	for(int i=2;i<=n;i++)
	{
		if(mp[s][i]&&!vis[i])
		{
			t=i;
			break;
		 } 
	}
	ans[cnt++]=s;
	ans[cnt++]=t;	
	while(1)
	{		
		expand();
		swap(s,t);
		_reverse(0,cnt-1);
		expand();		
		if(!mp[s][t])
		{
			for(int i=1;i<cnt-2;i++)
			{
				if(mp[i][t]&&mp[i+1][s])
				{
					_reverse(i+1,cnt-1);
					t=ans[cnt-1];
					
				}
			}		
		}		
		if(cnt==n)
		{
			break;
		}		
		int mid;		
		for(int i=1;i<=n;i++)
		{
			int flag=0;
			if(!vis[i])
			{
				for(int j=0;j<cnt;j++)
				{
					if(mp[ans[j]][i])
					{
						t=i;mid=j;flag=1;
						break;					
					}				
				}		
			}		
			if(flag)
			break;
		}		
		s=ans[mid-1];
		_reverse(0,mid-1);
		_reverse(mid,cnt-1);
		ans[cnt++]=t;
		vid[t]=1;
		
	}

} 

一位學姐的代碼
在這裏插入圖片描述
在這裏插入圖片描述基於競賽圖的哈密頓迴路的求解方法

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述另一種寫法,靈活,但是不宜理解
在這裏插入圖片描述

發佈了52 篇原創文章 · 獲贊 41 · 訪問量 7258
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章