Loading

欧拉路与欧拉回路

1欧拉回路与欧拉路

1.1定义

  1. 给定一张无向图,若存在一条从s到t的路径,恰好不重不漏的经过每条边一次,则称改路径为s到t的欧拉路。
  2. 特别的,若存在一条从s到s的欧拉路,则称该路径为欧拉回路,存在欧拉回路的图被称为欧拉图。

2.1定理

  1. 欧拉图:一张无向图为欧拉图,当且仅当无向图连通,并且每个点的度数都是偶数。
  2. 欧拉图=路的存在性判定:一张无向图存在欧拉路,当且仅当无向图联通,并且图中恰好有两个节点的度数为奇数,其他节点的度数都是偶数,这两个度数为奇数的节点就是欧拉路的起点s和t。

2求欧拉回路:

注意:

  1. 用栈完成拼接
  2. 用栈模拟递归
  3. 注意类似于“当前弧优化”
  4. 输出时倒着输出
  5. 时间复杂度:\(O(N+M)\)

代码:

inline void ouler(){
    stack[++top]=1;
    while(top>0){
        int x=stack[top],i=head[x];
        while(i&&vis[i]) i=next[i];
        if(i){
            stack[++top]=ver[i];;
            vis[i]=vis[i^1]=1;
            head[x]=next[i];
        }
        else{
            top--;
            ans[++t]=x;
        }
    }
} 

for(int i=t;i>=1;i--) printf("%d",ans[i]);

3例题:

P1333

欧拉路的裸题,提醒:用引用来优化map,不用来回调用。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<deque>
#include<cstdlib>
#include<ctime>
#define dd double
#define ld long double
#define ll long long
#define ull unsigned long long
#define N 601000
#define M 601000
using namespace std;

const int INF=0x3f3f3f3f;

inline ll read(){
	ll x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct edge{
    int to,next;
    inline void intt(int to_,int ne_){
        to=to_;next=ne_;
    }
};
edge li[M];
int head[N],tail;

inline void add(int from,int to){
    li[++tail].intt(to,head[from]);
    head[from]=tail;
}

map<string,int> Map;
int tot;

int d[N],sum;
bool vis[N];

inline void dfs(int k){
    vis[k]=1;
    for(int x=head[k];x;x=li[x].next){
        int to=li[x].to;
        if(vis[to]) continue;
        dfs(to);
    }
}

int main(){
    while(1){
        string s1,s2;
        cin>>s1>>s2;
        if(s1=="\000") break;
        int &from=Map[s1],&to=Map[s2];
        if(!from) from=++tot;
        if(!to) to=++tot;
        add(from,to);add(to,from);
        d[from]++;d[to]++;
    }
    dfs(1);
    for(int i=1;i<=tot;i++){
        if(!vis[i]){
            printf("Impossible\n");
            return 0;
        } 
        if(d[i]%2==1) sum++;
    }
    if(sum!=2&&sum!=0){
        printf("Impossible\n");
        return 0;
    }
    printf("Possible\n");
    return 0;
}
posted @ 2021-04-05 16:40  hyl天梦  阅读(210)  评论(0编辑  收藏  举报