歐拉回路和歐拉路徑

在一張圖中,從一個點出發每條邊經過且只經過一次得到的路徑,如果最后回到起點,那么就是歐拉回路,如果最后沒有回到起點,那么得到的就是歐拉路徑。

在無向圖中,歐拉路徑滿足的要求是,除了起點和終點以外其他點的度數都是偶數;歐拉回路滿足的要求是所有點的度數都是偶數。

在有向圖中,歐拉路徑滿足的要求是:除了起點和終點外,其他點的出度等于入度,起點的出度比入度多1,終點的入度比出度多1;在歐拉回路中,所有點的出度等于入度。

通常找歐拉路徑的算法就是dfs遍歷,但是這里的判重是判重邊,而非判重點。而且是當一個點所有的邊都遍歷結束后才會將該點算入答案。我們以一個點為例,若有m條自環路徑,那么每條路徑出就要開一層,一直往下遞歸。那么時間復雜度就變成m^2,這個時間復雜度很高,所有我們由此產生優化,遍歷一條邊那么就把它刪掉,以防后面再次遍歷到這條邊,產生不必要的冗余。但是這里如果僅僅通過h[u]=ne[i]來刪除,后面遍歷時可以生效,但是回溯到前面遍歷并不是再從開頭開始,所以并沒有生效(或者換個角度來理解,我們的刪除相當于直接將頭節點的指針往后移,但是中間節點的指針是沒有改變的,所以實際上前面的循環應該已經到了中間那么節點的部分,它們之間的指向關系并沒有改變,仍然會產生新的遞歸循環)時間復雜度還是很高,那么該如何處理呢,我們這里通過傳入指針來實現動態的刪除。

void dfs(int u)
{for (int &i = h[u]; ~i;){if (used[i]){i = ne[i];continue;}used[i] = true;if (type == 1) used[i ^ 1] = true;int t;if (type == 1){t = i / 2 + 1;if (i & 1) t = -t;}else t = i + 1;int j = e[i];i = ne[i];dfs(j);ans[ ++ cnt] = t;}
}

我們在定義的時候定義int &i=h[u],修改i的時候,h[u]也被同步修改了,往后遞歸的時候,我們每次都從h[u]開始,h[u]不是一成不變的,修改i相當于修改h[u],修改h[u]相當于修改中間節點的指向,中間節點的指向關系變了,那么往前回溯的過程中就不會出現剛剛m^2的問題了。

1123. 鏟雪車(活動 - AcWing)

這里有個很迷惑人的條件,鏟雪的時候前進速度是20,不鏟雪的時候前進速度是50,但是顯然不鏟雪的前提是學已經鏟過了,那么就相當于這條路走了兩邊,當然是只走一遍更劃算。每條道路的兩個方向均需要鏟雪,所以每條路徑的出度等于入度,那么就是歐拉回路,所以我們可以保證每條路徑只經過一次,所以我們統計出所有的路徑再除20即可。這里的時間轉化,我們可以先求出分鐘數,然后再進行轉化。

#include<bits/stdc++.h>
using namespace std;
int s,t;
double getd(double a,double b,double c,double d)
{double dx=a-c,dy=b-d;double res=dx*dx+dy*dy;return sqrt(res);
}
int main()
{scanf("%d%d",&s,&t);double a,b,c,d;double ans=0;while(~scanf("%lf%lf%lf%lf",&a,&b,&c,&d)){double sd=getd(a,b,c,d);ans += 2*sd;}int m=round(ans/1000/20*60);int h=m/60;m%=60;printf("%d:%02d",h,m);}

1184. 歐拉回路(活動 - AcWing)

要注意,歐拉回路和歐拉路徑中是可以有孤立點的,經過所有邊,不一定經過所有點,所以dfs要找一個有出邊的點開始遍歷/

#include<bits/stdc++.h>
using namespace std;
const int N=100010,M=400010;
int t,n,m;
int cnt;
int ans[M],used[M];
int h[N],e[M],ne[M],idx;
int din[N],dout[N];
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{for(int &i = h[u];~i;){if(used[i]){i=ne[i];continue;}used[i]=1;if(t==1) used[i^1]=1;int res;if(t==1){res=i/2+1;if(i&1) res*=-1;}else res=i+1;int j=e[i];i=ne[i];dfs(j);ans[++cnt]=res;}}
int main()
{scanf("%d%d%d",&t,&n,&m);memset(h,-1,sizeof h);for(int i=1;i<=m;i++){int a,b;scanf("%d%d",&a,&b);add(a,b);if(t==1) add(b,a);din[b]++,dout[a]++;}if(t==1){for(int i=1;i<=n;i++){if(din[i]+dout[i]&1){printf("NO");return 0;}}}else{for(int i=1;i<=n;i++){if(din[i]!=dout[i]){printf("NO");return 0;}}}for(int i=1;i<=n;i++){if(h[i]!=-1){dfs(i);break;}}if(cnt!=m) printf("NO\n");else{printf("YES\n");for(int i=cnt;i>=1;i--){printf("%d ",ans[i]);}}
}

?另外要注意我們dfs求得的路徑是從終點到起點的,所以輸出的時候需要倒著輸出。

1124. 騎馬修柵欄(1124. 騎馬修柵欄 - AcWing題庫)

這里我們需要輸出經過的節點,同時使得在有多組解的情況下輸出節點序最小的那組解。那么我們首先應該找到最小的有出邊的點,從這里開始遍歷,另外為了使得后面的點也是小的在前面,我們需要先遍歷所有出邊中連接的點編號最小的出邊,那么可以用鄰接矩陣來存邊。

本題不確定是求歐拉回路還是歐拉路徑,所以我們先找出第一個有邊的點,然后遍歷查找是否有度為奇數點,如果有就替換,否則就直接搜歐拉回路。

#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n;
int g[N][N],ans[N*N],cnt,d[N];
void dfs(int u)
{for(int i=1;i<=500;i++){if(g[u][i]){g[u][i]--,g[i][u]--;dfs(i);}}ans[++cnt]=u;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){int a,b;scanf("%d%d",&a,&b);g[a][b]++,g[b][a]++;d[a]++,d[b]++;}int s=1;while(!d[s])s++;for(int i=s;i<=500;i++){if(d[i]%2) {s=i;break;}}dfs(s);for(int i=cnt;i>=1;i--) printf("%d\n",ans[i]);}

1185. 單詞游戲(活動 - AcWing)

思路:這里如果將單詞視為節點顯然建邊太麻煩了,我們可以用之前的一個思路,在一個單詞的首尾字母之間建邊,這樣的話就只有26個點,實現復雜度一下就降低了。

?那么就要想是建有向邊還是無向邊,我們要注意順序問題,所以建的是有向邊。然后實際上不用真的去搜,只需要判斷一下每個點的出度入度是否符合要求,然后判斷一下邊是否連通。這里判斷邊是否連通不用dfs,我們用并查集來判斷。

#include<bits/stdc++.h>
using namespace std;
const int N=30,M=200010;
int st[M];
int dout[N],din[N];
int p[N];
int find(int x)
{if(x!=p[x]) p[x]=find(p[x]);return p[x];
}
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);memset(st,0,sizeof st);memset(din,0,sizeof din);memset(dout,0,sizeof dout);for(int i=0;i<26;i++) p[i]=i;for(int i=1;i<=n;i++){string s;cin>>s;int a=s[0]-'a',b=s[s.size()-1]-'a';st[a]=st[b]=1;dout[a]++,din[b]++;p[find(a)]=find(b);}int flag=1,sc=0,ec=0;for(int i=0;i<26;i++){if(dout[i]-din[i]==1) sc++;else if(din[i]-dout[i]==1) ec++;else if(din[i]!=dout[i]) {flag=0;break;}}if (flag && !(!sc && !ec || sc== 1 && ec == 1)) flag = 0;int rep=-1;for(int i=0;i<26;i++){if(st[i]){if(rep==-1) rep=find(i);else if(rep!=find(i)){flag=0;break;}}}if(!flag) printf("The door cannot be opened.\n");else printf("Ordering is possible.\n");}
}

這題判斷邊是否連通也可以用dfs來寫,只不過時間復雜度太高了,會超時,這里還是把代碼放上。

#include<bits/stdc++.h>
using namespace std;
const int N=30,M=200010;
int st[M];
int dout[N],din[N];
int p[N];
int h[N],e[M],ne[M],idx;
int used[M];
int cnt;
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{for (int &i = h[u]; ~i;){if (used[i]){i = ne[i];continue;}used[i] = true;int j = e[i];i = ne[i];dfs(j);cnt++;}
}
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);memset(used,0,sizeof used);memset(din,0,sizeof din);memset(dout,0,sizeof dout);memset(h,-1,sizeof h);for(int i=1;i<=n;i++){string s;cin>>s;int a=s[0]-'a',b=s[s.size()-1]-'a';dout[a]++,din[b]++;add(a,b);}int flag=1,sc=0,ec=0;for(int i=0;i<26;i++){if(dout[i]-din[i]==1) sc++;else if(din[i]-dout[i]==1) ec++;else if(din[i]!=dout[i]) {flag=0;break;}}if (flag && !(!sc && !ec || sc== 1 && ec == 1)) flag = 0;if(!flag) printf("The door cannot be opened.\n");//判連通else {int s=0;while(!dout[s]) s++;for(int i=0;i<26;i++)if(dout[i]-din[i]==1){s=i;break;}dfs(s);if(cnt<n) printf("The door cannot be opened.\n");else printf("Ordering is possible.\n");}}
}

所以可以見得,判斷歐拉回路和歐拉路徑,只要判斷度和連通性的性質滿足即可,方法不唯一。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696404.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696404.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DM數據庫學習之路(十六)DEM部署DM8DPC集群

DEM部署DPC集群 DPC準備工作 在所有安裝DPC服務器上部署dmagent&#xff0c;dmagent的運行環境需要依賴JAVA環境&#xff0c;JAVA版本必須為JAVA1.8。 創建用戶 所有安裝DPC服務器&#xff0c;手工建dmdba用戶 # groupadd dinstall # useradd -g dinstall -d /home/dmdba…

并發編程之深入理解Java線程

并發編程之深入理解Java線程 線程基礎知識 線程和進程 進程 程序由指令和數據組成、但這些指令要運行&#xff0c;數據要讀寫&#xff0c;就必須要將指令加載至CPU、數據加載至內存。在指令運行過程中還需要用到磁盤、網絡等設備。進程就是用來加載指令、管理內存、管理IO的…

Jmeter內置變量 vars 和props的使用詳解

JMeter是一個功能強大的負載測試工具&#xff0c;它提供了許多有用的內置變量來支持測試過程。其中最常用的變量是 vars 和 props。 vars 變量 vars 變量是線程本地變量&#xff0c;它們只能在同一線程組內的所有線程中使用&#xff08;線程組內不同線程之間變量不共享&#…

模型轉換案例學習:等效替換不支持算子

文章介紹 Qualcomm Neural Processing SDK &#xff08;以下簡稱SNPE&#xff09;支持Caffe、ONNX、PyTorch和TensorFlow等不同ML框架的算子。對于某些特定的不支持的算子&#xff0c;我們介紹一種算子等效替換的方法來完成模型轉換。本案例來源于https://github.com/quic/qidk…

并發編程(2)基礎篇-管程

4 共享模型之管程 本章內容 共享問題synchronized線程安全分析Monitorwait/notify線程狀態轉換活躍性Lock 4.1 共享帶來的問題 4.1.1 小故事 老王&#xff08;操作系統&#xff09;有一個功能強大的算盤&#xff08;CPU&#xff09;&#xff0c;現在想把它租出去&#xff…

基礎小白快速入門Python->Python中的類

什么是類&#xff1f; 在編程語言中&#xff0c;類&#xff08;Class&#xff09;是一個用于創建對象的藍圖或模板。它定義了對象的屬性&#xff08;也稱為成員變量&#xff09;和方法&#xff08;也稱為成員函數&#xff09;。類是面向對象編程&#xff08;OOP&#xff09;的…

2024 全國水科技大會暨第二屆智慧水環境管理與技術創新論壇

論壇二&#xff1a;第二屆智慧水環境管理與技術創新論壇 召集人&#xff1a;劉炳義 武漢大學智慧水業研究所所長、教授 為貫徹落實中共中央國務院印發《數字中國建設整體布局規劃》和國務院關于印發《“十四五”數字經濟發展規劃》的通知&#xff0c;推動生態環境智慧治理&…

L2 清點代碼庫----PTA(疑問)

上圖轉自新浪微博&#xff1a;“阿里代碼庫有幾億行代碼&#xff0c;但其中有很多功能重復的代碼&#xff0c;比如單單快排就被重寫了幾百遍。請設計一個程序&#xff0c;能夠將代碼庫中所有功能重復的代碼找出。各位大佬有啥想法&#xff0c;我當時就懵了&#xff0c;然后就掛…

docker pullpush 生成鏡像文件并push 到阿里云

pull docker docker pull ultralytics/ultralytics # 拉取yolov8的鏡像倉庫 docker run -it ultralytics/ultralytics # 運行鏡像 conda create -n gsafety python3.8 # 創建環境 source activate gsafety # 激活環境 pip install -i https://pypi.tuna.tsinghua.edu.cn/simp…

糖尿病性視網膜病變(DR)的自動化檢測和分期

糖尿病性視網膜病變&#xff08;DR&#xff09;的自動化檢測和分期 提出背景DR的階段及其特征 歷年解法計算機視覺方法多分類方法 新的解法深度學習方法遷移學習大模型多模型集成全流程分析 總結特征1&#xff1a;圖像分割特征2&#xff1a;疾病分級特征3&#xff1a;治療建議生…

開源模型應用落地-工具使用篇-獲取文本向量(五)

一、前言 在之前學習的"開源模型應用落地-工具使用篇"系列文章中&#xff0c;我們已經學會了如何使用向量數據庫。然而&#xff0c;還有一個問題一直未解決&#xff0c;那就是如何處理文本向量。在本文中&#xff0c;我們將繼續深入學習關于向量的知識&#xff0c;特…

Redis的哨兵系統

Redis 哨兵&#xff08;Sentinel&#xff09;系統是一種用于管理多個 Redis 服務器的系統&#xff0c;其主要目標是提供監控、通知、自動故障轉移和服務發現功能。哨兵系統能夠在 Redis 實例出現問題時自動進行故障轉移&#xff0c;確保系統的高可用性。其工作原理如下&#xf…

常見消息中間件

ActiveMQ 我們先看ActiveMQ。其實一般早些的項目需要引入消息中間件&#xff0c;都是使用的這個MQ&#xff0c;但是現在用的確實不多了&#xff0c;說白了就是有些過時了。我們去它的官網看一看&#xff0c;你會發現官網已經不活躍了&#xff0c;好久才會更新一次。 它的單機吞…

2024年學習的最高薪酬編程語言

2024年學習的最高薪酬編程語言 10. Scala Scala是一種在Java虛擬機&#xff08;JVM&#xff09;上運行的函數式編程語言。它通常用于大數據處理、機器學習和后端Web開發。 關于Scala編程語言及其常見用途的要點如下&#xff1a; Scala是一種通用編程語言&#xff0c;運行在J…

mac真的安裝不了vmware嗎 mac如何安裝crossover crossover序列號從哪里買 購買正版渠道

有些用戶可能想在mac上運行一些只能在windows上運行的軟件&#xff0c;比如游戲、專業軟件等。這時候&#xff0c;就需要用到虛擬機技術&#xff0c;也就是在mac上安裝一個可以模擬其他操作系統的軟件&#xff0c;比如vmware或者crossover。那么&#xff0c;mac真的安裝不了vmw…

2024年華為OD機試真題-貪心歌手-Python-OD統一考試(C卷)

題目描述: 一個歌手準備從A城去B城參加演出。 1) 按照合同,他必須在T天內趕到。 3) 歌手不能往回走。 4) 每兩座城市之間需要的天數都可以提前獲知。 5) 歌手在每座城市都可以在路邊賣唱賺錢。經過調…

【前端素材】推薦優質后臺管理系統Xoric平臺模板(附源碼)

一、需求分析 當我們從多個層次來詳細分析后臺管理系統時&#xff0c;可以將其功能和定義進一步細分&#xff0c;以便更好地理解其在不同方面的作用和實際運作。 1. 功能層次 a. 用戶管理功能&#xff1a; 用戶注冊和登錄&#xff1a;管理用戶賬戶的注冊和登錄過程。權限管…

K8S故障處理指南:網絡問題排查思路

1. 前言 對于私有化環境&#xff0c;客戶的網絡架構&#xff0c;使用的云平臺存在著各種差異&#xff0c;K8S網絡可能會出現各種問題&#xff0c;此文著重講解遇到此種問題的排查方法和思路&#xff0c;不會涉及相關網絡底層技術描述. 環境說明 由于我們的k8s網絡組件默認使…

5.網絡游戲逆向分析與漏洞攻防-游戲網絡架構逆向分析-測試需求與需求拆解

內容參考于&#xff1a;易道云信息技術研究院VIP課 上一個內容&#xff1a;模擬游戲登陸器啟動游戲并且完成注入 首先正常分析軟件程序有沒有漏洞&#xff0c;需要通過它的操作侵入&#xff0c;比如買東西&#xff0c;就通過買東西的按鈕它背后有源代碼就看源代碼&#xff0c…

TypeScript學習筆記-基礎

一、type 和 interface type和 interface的區別&#xff1a;TypeScript 中文網: 文檔 - 日常類型 type類型別名和interface接口非常相似&#xff0c;在很多情況下可以在它們之間自由選擇。interface 的幾乎所有功能都在 type 中可用&#xff0c;主要區別在于無法重新打開類型…