2025.8.6 圖論(1)Solution

2025.8.6 圖論(1)Solution

割點

學習資料,在 csdn 或洛谷上看都行。是模板題題解(之一)。

T1:Atserckcn與逃離恐怖老師。

題意簡述:從一個圖中選定一個點,使得刪除這個點后圖不連通。求該點編號,無解輸出 -1。圖不一定聯通。

那么本題顯然就是割點模板題,在模板題代碼中稍微修改即可。

最小生成樹

最小生成樹一般有兩種算法:Kruskal and Prim。

kruskal

基本思想:采取貪心的思想,對邊按邊權為關鍵字,從小到大排序。遍歷所有邊,用并查集維護邊連接的兩個點。如果兩個點之前并不在一個連通塊中,那么此邊就是最小生成樹中的其中一個邊。反之跳過。直至選擇了 n?1n-1n?1 條邊,變成了一棵樹。

實例代碼:

sort(edge+1,edge+m+1,cmp);//對邊進行排序for(int i=1;i<=m;i++)//遍歷每條邊{if(!Union(edge[i].u,edge[i].v))//檢查u,v是否在同一連通塊{//是的話,選取這條邊。ans+=edge[i].w;cnt++;}if(cnt>=n-1){break;}}
Prim

思想:也是運用貪心的思想,不過不同于 Kruskal 的是,Kruskal 是按照邊進行貪心選取,而 Prim 是基于點。

  • 一開始先將點 111 加入生成樹。

  • 維護一個數組,表示每個點到目前最小生成樹的距離,執行 n?1n-1n?1 次,每次選取最近的一個點加入生成樹,并更新距離。

for(re int i=2;i<=n;++i)dis[i]=inf;for(re int i=head[1];i;i=e[i].next)dis[e[i].v]=min(dis[e[i].v],e[i].w);//更新while(++tot<n)//再次加入n-1個點{int minn=inf;vis[now]=1;for(int i=1;i<=n;++i){if(!vis[i]&&minn>dis[i]){minn=dis[i];now=i;}}ans+=minn;//更新disfor(int i=head[now];i;i=e[i].next){int v=e[i].v;if(dis[v]>e[i].w&&!vis[v])dis[v]=e[i].w;}}return ans;

從TJ區搞過來的,大家可以自行試試。

T2:Atserckcn 與選取隧道

原題:YZOJ P1038 – 隧道

思路:

  • 因為道路/隧道需要連接每個島,并且它們的建設數量要最小,所以不難看出總結果一定是一棵樹。
  • 島上的居民喜歡隧道,而不是橋梁,那么就多選隧道。
  • 隧道對答案的貢獻是 000
  • 橋梁對答案的貢獻是 111
  • 可以將每條隧道的權值設為 000,橋梁的權值設為 111,用 Kruskal 或 Prim 實現

實現代碼:(kruskal)

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5,K=1.2e4+5,M=K;
int n,k,m,fa[N],cnt_e,ans,cnt;
struct E{int from,to,w;
}e[K+M];
bool operator < (const E &x,const E &y)//按照權值小到大排序
{return x.w<y.w;
}
int findfa(int x)//并查集部分
{return fa[x]==x?x:fa[x]=findfa(fa[x]);
}
void Union(int x,int y)
{fa[findfa(x)]=findfa(y);return;
}
void kruskal()
{sort(e+1,e+cnt_e+1);for(int i=1;i<=cnt_e;++i){int u=e[i].from,v=e[i].to,w=e[i].w;if(findfa(u)!=findfa(v)){Union(u,v);++cnt;ans+=w;if(cnt>=n-1)break;}}return;
}
int main(){ios::sync_with_stdio(0);cin>>n>>k>>m;for(int i=1;i<=n;++i)fa[i]=i;for(int i=1;i<=k;++i){++cnt_e;cin>>e[cnt_e].from>>e[cnt_e].to;e[cnt_e].w=0;}for(int i=1;i<=m;++i){++cnt_e;cin>>e[cnt_e].from>>e[cnt_e].to;e[cnt_e].w=1;}kruskal();cout<<ans<<'\n';return 0;
}

縮點

前置知識點:強連通分量。學習資料。

原題:YZOJ P1332 – Love

對于本題,O(n2)O(n^2)O(n2) 的枚舉肯定超時,考慮優化。

將粉絲視為點,uuu 崇拜 vvv 則當為一條連接 (u,v)(u,v)(u,v) 的有向邊。

  • 如果某個連通塊里的所有人都互相崇拜,那么這一大塊的人目前都是最無腦粉絲
  • 考慮運用強連通分量,將上述的所有互相崇拜的聯通塊視作一個點,在新圖上操作。
  • 接下來看出度,如果這個點沒有出度,說明他們沒有崇拜的人,都可能是最佳無腦粉絲
  • 但是如果有兩個以上這樣的連通塊,最佳無腦粉絲就一個都不是。

實例代碼:

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5,M=1e6+5;
int n,m,ehead[N],cnt_e,dfn[N],low[N],idx,tot,belong[N],deg[N],siz[N],ans,cntans;
stack<int> st;
bool inst[N];
struct E{int to,pre;
}e[M];
void adde(int from,int to)
{e[++cnt_e].to=to;e[cnt_e].pre=ehead[from];ehead[from]=cnt_e;return;
}
void dfs(int u)
{low[u]=dfn[u]=++idx;inst[u]=1;st.push(u);for(int i=ehead[u];i;i=e[i].pre){int v=e[i].to;if(!dfn[v]){dfs(v);low[u]=min(low[u],low[v]);}elseif(inst[v])low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){vector<int> vec;vec.clear();++tot;while(1){int t=st.top();st.pop();vec.push_back(t);inst[t]=0;if(t==u)break;}for(int i=0;i<(int)vec.size();++i)belong[vec[i]]=tot;for(int i=0;i<(int)vec.size();++i){int u=vec[i];for(int j=ehead[u];j;j=e[j].pre){int v=e[j].to;if(belong[v]!=tot)++deg[tot];}}siz[tot]=vec.size();
//		cout<<tot<<":\n";
//		for(int i=0;i<(int)vec.size();++i)
//			cout<<vec[i]<<' ';
//		cout<<'\n';vec.clear();}return;
}
int main(){ios::sync_with_stdio(0);cin>>n>>m;for(int i=1,u,v;i<=m;++i){cin>>u>>v;adde(u,v);}for(int i=1;i<=n;++i)if(!dfn[i])dfs(i);
//	for(int i=1;i<=n;++i)
//		cout<<belong[i]<<' ';
//	cout<<'\n';for(int i=1;i<=tot;++i){if(!deg[i]){ans+=siz[i];++cntans;}}if(cntans>1){cout<<"0\n";return 0;}cout<<ans<<'\n';return 0;
}

LCA

學習資料。

對于本題,由于在一棵樹上,兩點的距離就是兩點 a,ba,ba,b 到根節點(假定為 111)的距離減去兩倍根節點到 LCA(a,b)LCA(a,b)LCA(a,b) 的距離,不懂畫個圖就懂。

示例代碼:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,q,cnt_e,ehead[N],dis[N],fa[N][25],dep[N];
struct E{int to,w,pre;
}e[N<<1];
void adde(int from,int to,int w)
{e[++cnt_e].to=to;e[cnt_e].w=w;e[cnt_e].pre=ehead[from];ehead[from]=cnt_e;return;
}
void dfs(int u,int u_f)
{fa[u][0]=u_f;for(int i=1;i<=20;++i)fa[u][i]=fa[fa[u][i-1]][i-1];for(int i=ehead[u];i;i=e[i].pre){int v=e[i].to,w=e[i].w;if(v==u_f)continue;dis[v]=dis[u]+w;dep[v]=dep[u]+1;dfs(v,u);}return;
}
int getlca(int x,int y)
{if(dep[x]<dep[y])swap(x,y);//dep[x]>=dep[y]for(int i=20;i>=0;--i)//倍增{if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];}if(x==y)return x;for(int i=20;i>=0;--i){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return fa[x][0];
}
int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>q;for(int i=1,u,v,w;i<n;++i){cin>>u>>v>>w;adde(u,v,w);adde(v,u,w);}dfs(1,1);while(q--){int x,y,lcaxy;cin>>x>>y;lcaxy=getlca(x,y);cout<<dis[x]+dis[y]-2*dis[lcaxy]<<'\n';}return 0;
}

題目講解完畢,看一些其他算法:

單源最短路——Floyd 算法

本質是個 dp,用 fk,i,jf_{k,i,j}fk,i,j? 表示只經過前 kkk 個點,i,ji,ji,j 之間的最短路徑。

每次轉移有兩種選擇:

  • 經過第 kkk 個點,fk,i,j=fk?1,i,k+fk?1,k,jf_{k,i,j}=f_{k-1,i,k}+f_{k-1,k,j}fk,i,j?=fk?1,i,k?+fk?1,k,j?
  • 不經過,fk,i,j=fk?1,i,jf_{k,i,j}=f_{k-1,i,j}fk,i,j?=fk?1,i,j?

注意到 fk,i,jf_{k,i,j}fk,i,j? 的轉移只跟 fk?1,i,jf_{k-1,i,j}fk?1,i,j? 有關系,所以可以省去 kkk 這一維,運用狀態的繼承性。

核心代碼:

for(int k=1;k<=n;++k)for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
問題:

那么 Floyd 可不可以判斷負環呢?如果可以,怎么判斷?如果不行,又為什么?

歐拉道路

學習資料。

不過有點冷門了,考試一般不會考……

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

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

相關文章

OpenBayes 教程上新丨一鍵部署 gpt-oss-20b,實測開源推理模型新 SOTA,性能直逼 o3?mini

時隔 6 年&#xff0c;自 GPT-2 以來&#xff0c;OpenAI 終于再度發布開源大模型——gpt-oss-120b 和 gpt-oss-20b&#xff0c;前者以千億級參數專為復雜推理與知識密集型場景設計&#xff0c;后者則更適合低延遲、本地或專業垂直領域使用&#xff0c;可在消費級硬件&#xff0…

nlp-句法分析

目錄 一、句法概述 1、成分語法理論概述 &#xff08;1&#xff09;分析過程 &#xff08;2&#xff09;缺點 2、依存語法理論概述 &#xff08;1&#xff09;依存關系、配價模式 &#xff08;2&#xff09;分類 &#xff08;3&#xff09;優勢&#xf…

linux磁盤加密

在Linux中&#xff0c;磁盤加密是一種保護數據不被未授權訪問的方法。有多種工具和策略可以實現磁盤加密&#xff0c;包括使用Linux內核的內置功能&#xff0c;如dm-crypt&#xff0c;以及使用更高級的解決方案&#xff0c;如LUKS&#xff08;Linux Unified Key Setup&#xff…

大數據架構演變之路

目錄 一、各階段的架構簡介 二、各個架構的詳細解釋 1. 傳統離線架構 2.1. Lambda架構-離線數倉分析實時鏈路分析 2.2. Lambda架構-離線數倉實時數倉 3. Kappa/流批一體架構 4. 湖倉一體架構 三、總結 一、各階段的架構簡介 技術架構 核心驅動(核心需求) ?關鍵技術 …

STM32 HAL庫驅動0.96寸OLED屏幕

STM32 HAL庫驅動0.96寸OLED屏幕 項目概述 本項目使用STM32 HAL庫為0.96寸OLED屏幕編寫驅動程序。OLED屏幕通過I2C接口與STM32單片機通信&#xff0c;實現文本、數字和圖形的顯示功能。 項目倉庫地址&#xff1a;STM32_Sensor_Drives 硬件連接 OLED屏幕通過I2C接口與STM32連…

橫向越權:修改參數訪問不屬于自己的數據

一、什么是橫向越權定義 橫向越權&#xff08;Horizontal Privilege Escalation&#xff09;是指 同一權限級別的用戶&#xff0c;通過篡改請求參數或資源標識&#xff0c;訪問本不屬于自己的數據或功能。例子 假設一個在線商城&#xff0c;用戶 A 訪問訂單詳情的 URL&#xff…

攻擊實驗(ARP欺騙、MAC洪范、TCP SYN Flood攻擊、DNS欺騙、DHCP餓死)

實驗一 ARP欺騙一、拓撲二、實驗準備、1.設置終端漏洞靶機集合選擇需要的數量和鏡像打開設備上的驅動精靈安裝網卡安裝成功后查看IP地址、網關信息等。三、實驗步驟1.實驗原理中間人&#xff08;攻擊者&#xff09;在終端與網關之間持續發送偽造的 ARP 應答包&#xff0c;雙向欺…

VSCode 禁用更新檢查的方法

通過設置菜單禁用 這是最直接和推薦的方法&#xff0c;可以永久禁用自動更新&#xff1a; 打開 VSCode。點擊左下角的齒輪圖標&#xff0c;然后選擇“設置”。或者通過菜單欄“文件” > “首選項” > “設置”進入。在頂部的搜索框中輸入“update”。找到“Update: Mode”…

Flutter - 應用啟動/路由管理

一、應用入口1. 初始化 Flutter 底層綁定 &#xff0c;運行 App。import package:flutter/material.dart; import package:flutter_base/Application.dart;void main() {// 確保綁定初始化WidgetsFlutterBinding.ensureInitialized();// App初始化Application.init(); }2. 注冊…

MySQL 數據操作全流程:創建、讀取、更新與刪除實戰

MySQL系列 文章目錄MySQL系列前言一、Create(創建)并插入數據1.1 單行數據 全列插入1.2 多行數據 指定列插入1.3 插入沖突時同步更新1.4 沖突時替換二、Retireve讀取數據2.1 全列查詢2.2 查詢指定列2.3 查詢字段為表達式2.4 結果去重 DISTINCT2.5 where條件篩選2.6 order by語…

SQL約束:數據完整性的守護者

在SQL中&#xff0c;約束&#xff08;Constraints&#xff09; 是作用于數據庫表字段上的規則&#xff0c;用于強制保證數據的完整性、準確性和一致性。當插入、更新或刪除數據時&#xff0c;約束會自動驗證操作是否符合規則&#xff0c;若違反則拒絕執行。 以下是SQL中常見的約…

Springboot-vue 地圖展現

在很多社區管理系統中&#xff0c;地圖展示功能是一個重要的模塊&#xff0c;它能直觀地呈現小區的地理位置分布。本文將詳細梳理從前端觸發請求到地圖上展示小區數據的完整流程&#xff0c;幫助大家理解前后端協同工作的具體細節。一、前端觸發&#xff1a;頁面加載與地圖初始…

Vue 3 登錄組件

Login.vue 組件詳細分析整體架構 Vue 3 登錄組件&#xff0c;采用 Composition API Element Plus UI 庫&#xff0c;實現了完整的用戶認證界面。 模板結構分析 1. 容器布局 <div class"login-container"><el-card class"login-card"><!-- …

小結: getSpringFactoriesInstances從 `spring.factories` 文件中加載和實例化指定類型的類

getSpringFactoriesInstances 方法工作原理 getSpringFactoriesInstances 是 Spring Boot 框架中的一個核心方法&#xff0c;用于從 spring.factories 文件中加載和實例化指定類型的類。這是 Spring Boot 實現自動配置和插件化擴展的關鍵機制。 1. 基本功能 該方法的主要作用是…

selenium SessionNotCreatedException問題解決辦法

在上周有一臺服務器重啟之后&#xff0c;Chrome瀏覽器也自動升了級&#xff0c;原本能夠正常使用的自動化辦公程序突然沒法用了&#xff0c;出現了下面的報錯提示。codes/addCancelBdld.py:980: DeprecationWarning: use options instead of chrome_optionsdriver webdriver.C…

SOAP HTTP Binding

SOAP HTTP Binding 引言 SOAP(Simple Object Access Protocol)是一種輕量級、簡單的協議,用于在網絡上交換結構化信息。它廣泛應用于Web服務中,用于實現不同系統和應用程序之間的通信。SOAP HTTP Binding是SOAP協議的一種實現方式,它允許使用HTTP協議來傳輸SOAP消息。本…

GPT-5免費使用教程(國內可訪問)

GPT-5來了&#xff0c;壓力給到各大AI模型廠商&#xff1f; 北京時間2025年8月7日&#xff0c;OpenAI 推出兩款開源模型 gpt-oss-120b / 20b&#xff0c;性能逼近 o4-mini/o3-mini&#xff0c;一時間火爆AI圈&#xff1b;但這好像只是一道開胃小菜&#xff0c;在北京時間2025年…

內存作假常見方案可行性分析

內存作假通常修改所涉及到的幾個文件&#xff1a;M sys/frameworks/base/core/java/android/app/ActivityManager.javaM sys/frameworks/base/core/jni/android_os_Debug.cppM sys/frameworks/base/core/jni/android_util_Process.cppM sys/frameworks/base/services/core/java…

C#(vs2015)利用unity實現彎管機仿真

以下是基于 Visual Studio 2015 和 Unity 實現彎管機仿真的完整技術流程&#xff0c;結合工業仿真開發的最佳實踐整理而成&#xff0c;涵蓋建模、通信、運動控制和交互邏輯等核心模塊&#xff1a;---一、環境配置與基礎框架搭建 1. Unity 與 VS2015 聯動 - 安裝 [Visual Studio…

華為USG防火墻雙機,但ISP只給了1個IP, 怎么辦?

華為USG防火墻雙機&#xff0c;但ISP只給了1個IP&#xff0c; 怎么辦&#xff1f; 華為USG雙機使用VRRP&#xff0c;需要3個Ip 本次聯通只給了 100.1.1.0/30 這一個互聯段 聯通側用了100.1.1.1&#xff0c; 我們這一側只有100.1.1.2 怎么辦&#xff1f; 找聯通多要幾個Ip&…