欧拉路与欧拉回路

概念

  1. 有向图 \(G\) 为欧拉回路:当且仅当 \(G\) 的基图联通,且所有顶点的入度等于出度。

  2. 有向图 \(G\) 为欧拉路:当且仅当 \(G\) 的基图联通,而且只存在一个顶点 \(u\) 的入度比出度大于1,只存在一个顶点 \(v\) 的出度比入度大于 1(即最多有两个点的入读不等于出度),而且只能从出度比入度大于1的顶点作为起点或者以入度比出度大于1的顶点作为起点才可把图中所有路径走完。

  3. 如果一个无向图是连通的,而且最多存在着两个几点(度数为奇数)那么一定存在欧拉道路,如果有两个奇点,那么它们必须是起点和终点,如果奇点不存在,可以从任意的点出发,最终一定会回到该点,成为欧拉回路。

对于欧拉道路来说,选择奇点作为出发点那么肯定能都一次性走完图中所有边

总结:

无向图中

欧拉路径:所有点的度数都为偶数或者存在两个点的度数为奇数

欧拉回路:所有点的度数都为偶数

有向图

欧拉路径:所有点的入度都等于出度或者存在两个点,一个起点(出度减入度等于1),一个终点(入度减出度等于1)

欧拉回路:所有点的入度都等于出度

Fleury算法

也称避桥法,是一个偏暴力的算法。

算法流程为每次选择下一条边的时候优先选择不是桥的边。

最简单的实现方法是每次删除一条边之后暴力跑一遍 Tarjan 找桥,时间复杂度是 \(O(m(n+m))=O(m^2)\)

Ford-Fulkerson(FF)

非常直觉的算法,直接dfs寻找增广路,找到就增广,找不到为止。

这个算法的复杂度是多少?会不会一直能找到增广路而陷入死循环呢?

由于最大流明显有限,每次增广当前流量必然增加,实际上是不会陷入死循环的。

值得注意的是,FF算法在二分图上跑的时候,表现很类似匈牙利算法。

using namespace std;
const int N=1e4;
int n,in[N],out[N];
string s;
struct node{
	int u,v,nxt;
}a[N];
void add(int u,int v){
	a[++cnt]=(node){u,v,head[u]};
    head[u]=cnt;
}
il int read(){
	int f=1,x=0;char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return f*x;
}
int main(){
	n=read();
    rep(i,1,n){
    	cin>>s;
        int l=s.length();
        rep(j,1,l-1){
        	add(s[i-1]-'a',s[i]-'a');
            in[(int)s[i]-'a']++;
            out[(int)s[i-1]-'a']++;
        }
    }
    int f=0;
    rep(i,1,52){
        if(abs(in[i]-out[i])>=1) {
        	if(!s)s=i;
            else t=i;
        ++f;
        if(f==2)break;
        }
    }
    if(ol(s)==t){
    	rep(i,1,cnt)
        cout<<pass[i+'a'];
    }
}
posted @ 2023-06-19 19:32  XYini  阅读(5)  评论(0)    收藏  举报