UOJ 117 歐拉回路 - 歐拉回路

一道裸題,WA了兩屏。。。

先貼出基本概念:
http://www.cnblogs.com/luyingfeng/p/3877338.html
· 無向圖
歐拉通路:有兩個或者沒有奇度數的節點的連通圖;若有則一定是一個奇節點到另一個的連通圖
歐拉回路:沒有奇度數節點的連通圖,那麼可以從任意一個節點出發回到該節點
· 有向圖
歐拉通路:所有節點入度=出度的連通圖;或者僅存在兩個節點,其入度-出度分別爲-1,1的連通圖,對於後種情況一定是從-1的節點出發到達1節點
歐拉通路:所有節點入度=出度的連通圖

而遍歷這個圖時需要注意
這裏寫圖片描述
如上圖,到達B點時如果先走2路,那麼到達A’後回溯到B繼續走1路,如果先序記錄邊的順序,那麼到達A’後下一個記錄的邊會是1,構不成迴路,若將記邊放在後序,回溯時形成的將是一條完整的路,構成一個類似於棧的結構,反向輸出即可。

還有就是要加當前邊優化,學習了一波。

記得要判圖是否聯通!

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

const int maxn=200005;

struct edge
{
    int to,next;
    bool vst;
}e[maxn<<1];

int n,m,cnt,rcnt;
int head[maxn],in[maxn],out[maxn],res[maxn];
bool judge;

void insert(int a,int b)
{
    e[++cnt].to=b;e[cnt].next=head[a];head[a]=cnt;in[b]++;out[a]++;
}
bool judge1()
{
    for(int i=1;i<=n;i++)
        if(in[i]&1)return false;
    return true;
}
bool judge2()
{
    for(int i=1;i<=n;i++)
        if(in[i]!=out[i])return false;
    return true;
}
void dfs1(int x)
{

    for(int& i=head[x];i;i=e[i].next)
    {
        int tmp=i; 
        if(!e[i].vst)
        {
            e[i].vst=e[i^1].vst=true;
            dfs1(e[tmp].to);
            res[++rcnt]=(tmp>>1)*(tmp&1?-1:1);
        }
    }
}
void dfs2(int x)
{

    for(int& i=head[x];i;i=e[i].next)//i會變,用一個變量存一下 
    {
        int tmp=i;
        if(!e[i].vst)
        {
            e[i].vst=true;
            dfs2(e[tmp].to);
            res[++rcnt]=tmp;
        }
    }
}
void solve1()
{
    cnt=1;
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        insert(a,b),
        insert(b,a);
    }
    judge=judge1();
    if(m&&judge)dfs1(a);
    if(!m)judge=true;
}
void solve2()
{
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        insert(a,b);
    }
    judge=judge2();
    if(m&&judge)dfs2(a);
    if(!m)judge=true;
}
int main()
{
    int op;
    scanf("%d",&op);
    if(op==1)solve1();
    else solve2();
    if(!judge||rcnt!=m)puts("NO");
    else 
    {
        puts("YES");
        for(int i=rcnt;i;i--)
            printf("%d ",res[i]);
    }
    return 0;
}
發佈了112 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章