歐拉圖
歐拉圖:具有歐拉回路的圖叫做歐拉圖
歐拉回路:從起點出發,每條邊有且只經過一次,最終回到起點的路徑
歐拉通路:從起點出發,每條邊有且只經過一次,不要求回到其點的迴路
半歐拉圖,擁有歐拉通路,但不用有歐拉回路的圖叫做半歐拉圖
判斷方法
此外判斷一個圖是否立連通可已使用並查集
求歐拉回路的方法
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;
}
}
一位學姐的代碼
基於競賽圖的哈密頓迴路的求解方法
另一種寫法,靈活,但是不宜理解