1. 程式人生 > >尤拉圖

尤拉圖

詳解--------->請點這裡

 無向尤拉圖(半尤拉圖)逆序列印歐拉回路或通路程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100+5;
 
//無向圖列印尤拉路徑或迴路
//輸入保證是一個n頂點,m條邊的具有歐拉回路或尤拉路徑的無向圖
 
int n;//圖中頂點,頂點編號1到n
int m;//圖中邊
int G[maxn][maxn];
int vis[maxn][maxn];//vis[i][j]==1表示i與j點直接存在一條邊
 
//列印尤拉路徑或歐拉回路(必須本圖有尤拉路徑或迴路才行)
//列印的結果中最後一條邊才是u開始的,列印的第一條邊不一定是u開始的
//如果是列印尤拉路徑,那麼輸入的u一定要是起點之一,即度數為奇數的點之一
//否則euler列印的的邊不會構成尤拉路徑,只不過是亂序列印圖中所有的邊而已
void euler(int u)
{
    for(int v=1;v<=n;v++)if(vis[u][v]||vis[v][u])
    {
        //遞迴思想,去掉了u與v這條邊,
        //餘圖還是一個具有尤拉道路的圖,且v變成一個起點了
        vis[u][v]=vis[v][u]=0;
        euler(v);
        printf("%d %d\n",u,v);
    }
}
 
//輸出歐拉回路或路徑上按順序經過的節點
//u也必須要是起點之一,否則輸出的也是亂序點而已
void euler_point(int u)
{
    for(int v=1;v<=n;v++)if(vis[u][v] || vis[v][u])
    {
        vis[u][v]=vis[v][u]=0;
        euler_point(v);
    }
    printf("%d\n",u);
}
 
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(G,0,sizeof(G));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u][v]=G[v][u]=1;//無向圖
            vis[u][v]=vis[v][u]=1;
        }
 
        int u;
        scanf("%d",&u);
        euler_point(u);
 
    }
    return 0;
}

有向尤拉圖(半尤拉圖)逆序列印歐拉回路或通路程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100+5;
 
//有向圖列印尤拉路徑或迴路
//輸入保證是一個n頂點,m條邊的具有歐拉回路或尤拉路徑的有向圖
 
int n;//圖中頂點,頂點編號1到n
int m;//圖中邊
int G[maxn][maxn];
int vis[maxn][maxn];//vis[i][j]==1表示i到j點存在一條邊
 
//列印尤拉路徑或歐拉回路(必須本圖有尤拉路徑或迴路才行)
//列印的結果中最後一條邊才是u開始的,列印的第一條邊不一定是u開始的
//如果是列印尤拉路徑,那麼輸入的u一定要是起點之一,即abs(入度-出度)==1
//且如果是出度-入度==1的點,那麼該點就應該是尤拉圖的起點,但是會逆序輸出,所以最後才輸出
//否則euler列印的的邊不會構成尤拉路徑,只不過是亂序列印圖中所有的邊而已
void euler(int u)
{
    for(int v=1;v<=n;v++)if(vis[u][v])
    {
        //遞迴思想,去掉了u與v這條邊,
        //餘圖還是一個具有尤拉道路的圖,且v變成一個起點了
        vis[u][v]=0;
        euler(v);
        printf("%d %d\n",u,v);
    }
}
 
//逆序輸出歐拉回路或路徑上按順序經過的節點
//u也必須要是起點之一,否則輸出的也是亂序點而已
void euler_point(int u)
{
    for(int v=1;v<=n;v++)if(vis[u][v])
    {
        vis[u][v]=0;
        euler_point(v);
    }
    printf("%d\n",u);
}
 
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(G,0,sizeof(G));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u][v]=1;//有向圖
            vis[u][v]=1;
        }
 
        int u;
        scanf("%d",&u);
        euler(u);
 
    }
    return 0;
}