今天继续划水,来讲一讲欧拉路问题。
欧拉路,简单来说就是一笔画,即对于一张图,可以从某个点出发,经过每一条边,遍历完整张图,这个路径就称为欧拉路径。如果起点与终点重合,则称为欧拉回路。那么,应该如何判断欧拉路呢?
我们先定义几个概念,在无向图中,我们称有奇数条连接的边的点为奇点,有偶数条连接的边的点为偶点。对于有向图,我们设度数为出度减入度的值。
首先,应该判断连通性(dfs),如果这一个图不连通,则一定不是欧拉路。之后从其是否有向进行判断。
1.对于无向连通图,若节点全部为偶点,那么是欧拉回路,若只有两个奇点,其余全部为偶点,那么是欧拉路。
2.对于有向连通图,若所有的节点度数都为0,那么是欧拉回路,若起点度数为1,终点度数为-1,其余节点度数全部为0,那么是欧拉路。
例题1 hdu1878
欧拉回路
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23884 Accepted Submission(s): 9310
束。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=1005; 4 using ll = long long; 5 int du[maxn]; 6 bool vis[maxn]; 7 vector<int> g[maxn]; 8 void dfs(int x){ 9 vis[x]=1; 10 for(int i=0;i<g[x].size();i++){ 11 if(!vis[g[x][i]])dfs(g[x][i]); 12 } 13 } 14 int main() { 15 ios::sync_with_stdio(false); 16 cin.tie(0); 17 cout.tie(0); 18 int n,m; 19 while(1){ 20 cin>>n; 21 if(n==0)break; 22 cin>>m; 23 memset(du,0,sizeof(du)); 24 for(int i=1;i<=n;i++)g[i].clear(); 25 memset(vis,0,sizeof(vis)); 26 while(m--){ 27 int x,y; 28 cin>>x>>y; 29 g[x].push_back(y); 30 g[y].push_back(x); 31 du[x]++; 32 du[y]++; 33 } 34 int flag=1; 35 for(int i=1;i<=n;i++){ 36 if(du[i]&1){ 37 flag=0; 38 break; 39 } 40 } 41 dfs(1); 42 for(int i=1;i<=n;i++){ 43 if(!vis[i]){ 44 flag=0; 45 break; 46 } 47 } 48 cout<<flag<<endl; 49 } 50 return 0; 51 }
例题2 hdu1116
Play on Words
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12319 Accepted Submission(s): 4314
There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word ``acm'' can be followed by the word ``motorola''. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.
If there exists such an ordering of plates, your program should print the sentence "Ordering is possible.". Otherwise, output the sentence "The door cannot be opened.".
1 #include <bits/stdc++.h> 2 using namespace std; 3 using ll = long long; 4 const int maxn=30; 5 vector<int>g[maxn]; 6 bool vis[maxn]; 7 bool exi[maxn]; 8 int du[maxn]={0}; 9 void dfs(int x){ 10 vis[x]=1; 11 for(int i=0;i<(int)g[x].size();i++){ 12 int nex=g[x][i]; 13 if(!vis[nex])dfs(nex); 14 } 15 } 16 int main() { 17 ios::sync_with_stdio(false); 18 cin.tie(0); 19 cout.tie(0); 20 int t; 21 cin>>t; 22 while(t--){ 23 int m; 24 cin>>m; 25 int flag=1; 26 memset(exi,0,sizeof(exi)); 27 memset(du,0,sizeof(du)); 28 memset(exi,0,sizeof(exi)); 29 memset(vis,0,sizeof(vis)); 30 for(int i=0;i<maxn;i++)g[i].clear(); 31 while(m--){ 32 string s; 33 cin>>s; 34 int x=s[0]-'a',y=s[s.size()-1]-'a'; 35 g[x].push_back(y); 36 du[x]++; 37 du[y]--; 38 exi[x]=1; 39 exi[y]=1; 40 } 41 int cnt1=0; 42 int cnt2=0; 43 int cnt3=0; 44 int start=0; 45 for(int i=0;i<=25;i++){ 46 if(du[i]==1){ 47 cnt1++; 48 start=i; 49 } 50 if(du[i]==-1)cnt2++; 51 if(du[i]!=1&&du[i]!=0&&du[i]!=-1)cnt3++; 52 } 53 if((cnt1==1&&cnt2==1) || (cnt1==0&&cnt2==0))flag=1; 54 else flag=0; 55 if(cnt1&&cnt2&&(cnt1+cnt2>2))flag=0; 56 if(cnt3>0)flag=0; 57 dfs(start); 58 for(int i=0;i<=25;i++){ 59 if(exi[i]&&(!vis[i]))flag=0; 60 } 61 if(flag)cout<<"Ordering is possible."<<endl; 62 else cout<<"The door cannot be opened."<<endl; 63 } 64 return 0; 65 }
例题3 hdu5883
The Best Path
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3419 Accepted Submission(s): 1388
For each test case, in the first line there are two positive integers N (N≤100000) and M (M≤500000), as described above. The i-th line of the next N lines contains an integer ai(∀i,0≤ai≤10000) representing the number of the i-th lake.
The i-th line of the next M lines contains two integers ui and vi representing the i-th river between the ui-th lake and vi-th lake. It is possible that ui=vi.
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=(1e5)+5; 5 const int maxm=(5e5)+5; 6 ll a[maxn]; 7 ll du[maxn]; 8 int main(){ 9 int t; 10 cin>>t; 11 while(t--){ 12 int n,m; 13 memset(du,0,sizeof(du)); 14 scanf("%d%d",&n,&m); 15 for(int i=1;i<=n;i++)scanf("%lld",&a[i]); 16 for(int i=1;i<=m;i++){ 17 ll x,y; 18 scanf("%lld%lld",&x,&y); 19 du[x]++; 20 du[y]++; 21 } 22 int cnt=0; 23 int start; 24 for(int i=1;i<=n;i++){ 25 if(du[i]&1){ 26 cnt++; 27 start=i; 28 } 29 } 30 bool flag=1; 31 ll ans=0; 32 if(cnt==2){ //欧拉通路 33 for(int i=1;i<=n;i++){ 34 for(int j=1;j<=du[i]/2;j++){ 35 ans^=a[i]; 36 } 37 if(du[i]&1)ans^=a[i]; 38 } 39 } 40 else if(cnt==0){ //欧拉回路 41 for(int i=1;i<=n;i++){ 42 for(int j=1;j<=du[i]/2;j++){ 43 ans^=a[i]; 44 } 45 } 46 int ans0=ans; 47 for(int i=1;i<=n;i++){ 48 ans=max(ans0,ans0^a[i]); 49 } 50 } 51 else flag=0; 52 if(flag)printf("%lld\n",ans); 53 else printf("Impossible\n"); 54 } 55 return 0; 56 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧