欧拉路径杂题
欧拉路径杂题
欧拉路径:通过图中所有边恰好一次而且走遍了所有点(允许多次经过同一个点) 的通路是欧拉路径
如果这条路径的起点和终点重合 那么就是欧拉回路
注意 显然欧拉回路一定是欧拉路径的子集 下面讲一下分别判断的方式(即假定欧拉路径并不包含欧拉回路 这两个东西的判断是分开的)
判定:
- 有向图欧拉路径:图中恰好存在一个点
(作起点 一个点 (作终点) 其余所有节点 - 有向图欧拉回路:图中所有点的
- 无向图欧拉路径:图中恰好存在两个点的度数是奇数 其他为偶数
- 无向图欧拉回路:所有的点的度数都是偶数
P7771 【模板】欧拉路径
将每一个节点的出边排序 保证字典序最小 并加一个
同时 我们根据上面的
那么只有
最后用
总复杂度
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define mid (l+r>>1)
#define pii pair<int,int>
#define eb emplace_back
#define mkp make_pair
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f;
char buf[1<<24] , *p1 , *p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
// #define getchar() cin.get();
int read()
{
int x = 0 , f = 1;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f ;
}
int n , m , now[N] , rd[N] , cd[N] , sta[N] , top , cnt[2] , s = 1;
vector<int> e[N];
void add ( int u , int v ) { e[u].emplace_back(v); }
void dfs ( int u )
{
while ( now[u] < e[u].size() ) now[u] ++ , dfs(e[u][now[u]-1]);
sta[++top] = u;
}
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(nullptr) , cout.tie(nullptr);
n = read() , m = read();
for ( int i = 1 , u , v ; i <= m ; i ++ ) u = read() , v = read() , add ( u , v ) , rd[v] ++ , cd[u] ++;
for ( int i = 1 ; i <= n ; i ++ ) sort ( e[i].begin() , e[i].end() );
for ( int i = 1 ; i <= n ; i ++ )
{
if ( abs ( cd[i] - rd[i] ) > 1 ) return cout << "No" << endl , 0;
if ( cd[i] - rd[i] == 1 ) cnt[0] ++ , s = i;
else if ( rd[i] - cd[i] == 1 ) cnt[1] ++;
}
if ( ! ( ( cnt[0] == 1 && cnt[1] == 1 ) || ( cnt[0] == 0 && cnt[1] == 0 ) ) ) return cout << "No" << endl , 0;
dfs(s);
while ( top ) cout << sta[top--] << ' ';
return 0;
}
P2731 [USACO3.3] 骑马修栅栏 Riding the Fences
无向图欧拉路
和上一道题不一样的是 这道题需要用
如果有奇点 那么使它作为起点 否则默认为
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define mid (l+r>>1)
#define pii pair<int,int>
#define eb emplace_back
#define mkp make_pair
const int N = 1e3 + 5;
const int inf = 0x3f3f3f3f;
char buf[1<<24] , *p1 , *p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
// #define getchar() cin.get();
int read()
{
int x = 0 , f = 1;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f ;
}
int n , m , s = 1 , maxn , now[N] , sta[N] , top , deg[N];
vector<int> e[N];
void add ( int u , int v ) { e[u].emplace_back(v); }
map<pii,int> mp;
void dfs ( int u )
{
while(1)
{
while ( now[u] < e[u].size() && !mp[mkp(u,e[u][now[u]])] ) now[u] ++;
if ( now[u] >= e[u].size() ) break;
int v = e[u][now[u]];
now[u] ++ , mp[mkp(u,v)] -- , mp[mkp(v,u)] --;
dfs(v);
}
sta[++top] = u;
}
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(nullptr) , cout.tie(nullptr);
n = 550 , m = read();
for ( int i = 1 , u , v ; i <= m ; i ++ ) u = read() , v = read() , add ( u , v ) , add ( v , u ) , deg[u] ++ , deg[v] ++ , mp[mkp(u,v)] ++ , mp[mkp(v,u)] ++;
for ( int i = 1 ; i <= n ; i ++ ) sort ( e[i].begin() , e[i].end() );
for ( int i = 1 ; i <= n ; i ++ ) if ( deg[i] & 1 ) { s = i; break; }
dfs(s);
while ( top ) cout << sta[top--] << endl;
return 0;
}
P1341 无序字母对
同上一道题 可以暴力开点 直接用
注意有
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define mid (l+r>>1)
#define pii pair<int,int>
#define eb emplace_back
#define mkp make_pair
const int N = 125;
const int inf = 0x3f3f3f3f;
//char buf[1<<24] , *p1 , *p2;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
#define getchar() cin.get();
int read()
{
int x = 0 , f = 1;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f ;
}
int n , m , s , now[N] , sta[N] , top , deg[N] , cnt;
vector<int> e[N];
inl void add ( int u , int v ) { e[u].emplace_back(v); }
map<pii,int> mp;
void dfs ( int u )
{
while ( 1 )
{
while ( now[u] < e[u].size() && !mp[mkp(u,e[u][now[u]])] ) now[u] ++;
if ( now[u] >= e[u].size() ) break;
int v = e[u][now[u]];
now[u] ++ , mp[mkp(u,v)] -- , mp[mkp(v,u)] -- , dfs(v);
}
sta[++top] = u;
}
string ss;
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(nullptr) , cout.tie(nullptr);
n = read();
for ( int i = 1 , u , v ; i <= n ; i ++ ) cin >> ss , u = (int)(ss[0]) , v = (int)(ss[1]) , add ( u , v ) , add ( v , u ) , deg[u] ++ , deg[v] ++ , mp[mkp(u,v)] ++ , mp[mkp(v,u)] ++;
for ( int i = 'A' ; i <= 'z' ; i ++ ) { sort ( e[i].begin() , e[i].end() ); if ( deg[i] & 1 ) cnt ++; }
if ( cnt != 0 && cnt != 2 ) return cout << "No Solution" << endl , 0;
for ( int i = 'A' ; i <= 'z' ; i ++ ) if ( deg[i] ) { s = i; break; }
for ( int i = 'A' ; i <= 'z' ; i ++ ) if ( deg[i] & 1 ) { s = i; break; }
dfs(s);
if ( top < n + 1 ) return cout << "No Solution" << endl , 0;
while ( top ) cout << (char)(sta[top--]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下