欧拉路与欧拉回路
概念
-
有向图 \(G\) 为欧拉回路:当且仅当 \(G\) 的基图联通,且所有顶点的入度等于出度。
-
有向图 \(G\) 为欧拉路:当且仅当 \(G\) 的基图联通,而且只存在一个顶点 \(u\) 的入度比出度大于1,只存在一个顶点 \(v\) 的出度比入度大于 1(即最多有两个点的入读不等于出度),而且只能从出度比入度大于1的顶点作为起点或者以入度比出度大于1的顶点作为起点才可把图中所有路径走完。
-
如果一个无向图是连通的,而且最多存在着两个几点(度数为奇数)那么一定存在欧拉道路,如果有两个奇点,那么它们必须是起点和终点,如果奇点不存在,可以从任意的点出发,最终一定会回到该点,成为欧拉回路。
对于欧拉道路来说,选择奇点作为出发点那么肯定能都一次性走完图中所有边。
总结:
无向图中
欧拉路径:所有点的度数都为偶数或者存在两个点的度数为奇数
欧拉回路:所有点的度数都为偶数
有向图
欧拉路径:所有点的入度都等于出度或者存在两个点,一个起点(出度减入度等于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'];
}
}

浙公网安备 33010602011771号