luogu P3387 【模板】縮點

原題鏈接

原題再現

題目描述

給定一個?n?個點?m?條邊有向圖每個點有一個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。

允許多次經過一條邊或者一個點,但是,重復經過的點,權值只計算一次。

輸入格式

第一行兩個正整數?n,m。

第二行?n?個整數,其中第?i?個數?ai??表示點?i?的點權。

第三至?m+2?行,每行兩個整數?u,v,表示一條?u→v?的有向邊。

輸出格式

共一行,最大的點權之和。

題意簡述

有向圖,點都有點權。點可以經過多次,但點權只能加一次。

求這張圖的最大權值。

解題思路

如果一個強連通分量上的某個點被選中,那么選擇整個強連通分量顯然更優。因為這樣可以最大化點權總和。這樣一來,可以把整個強連通分量視為權值為強連通分量中所有點權值之和的整體點,選擇這個強連通分量上任意一點就意味著選擇整個強連通分量。所以縮點。

縮點,也就是將強連通分量合并為單點,將原來k個強連通分量的圖簡化成只有k個點的有向無環圖(DAG)。Tarjan算法實現。

Tarjan算法

在DFS搜索遍歷整個圖的過程中,把有向圖劃分為DFS搜索樹及非樹邊。

與傳統的DFS不同的是,多了回溯這一步。

非樹邊可以被分為:

  1. 返祖邊(回邊):從樹上的后代指向祖先,如7→1。
  2. 橫叉邊:無直接祖先關系且分屬不同子樹,如9→7。
  3. 前向邊:從樹上的祖先指向后代,如3→6。

在遇到非樹邊時,有相應的操作。

如果結點 u 是某個強連通分量在DFS搜索樹中遇到的第一個結點,那么這個強連通分量的其余結點肯定是在DFS搜索樹中以 u 為根的子樹中。結點 u 被稱為這個強連通分量的根。

關鍵數據結構

  • 數組dfn:dfn[i]表示第一次發現i的時間戳,亦可判斷是否為被訪問。
  • 數組low:low[i]表示i的追溯值,u或u的子樹能夠追溯到的最早的棧中節點的次序號。
  • 數組vis:vis[i]表示i是否正在訪問,即是否在棧中。
  • t:時間戳。
  • scc:強連通分量個數。
  • 棧st:棧保存了當前深度優先搜索(DFS)路徑上的所有節點。這些節點可能屬于同一個強連通分量,但尚未確認是否構成完整的SCC。用于追溯。
  • 數組color:每個節點標記其所屬的強連通分量編號。
void tarjan(int v) {dfn[v] = low[v] = ++tot; //標記dfn[]訪問順序,還有low[]的初始值sta.push(v);             //讓點v進棧vis[v] = true;           //標記這個點被訪問過for (int i = head[v]; ~i; i = edge[i].next) { //一直循環這個點每一個出度,直到-1表示沒有了,這也是為什么memset head數組時要賦-1int u = edge[i].to;               //定義u并把它賦成這條邊的終點if (!dfn[u]) {                    //如果u沒有被訪問過tarjan(u);                      //找下面這個點low[v] = min(low[v], low[u]);   //這個點low[v]的值就是當前low[]的值與找到的u點的low[]值} else if (vis[u])                //如果u被訪問過了,但是還在隊列中low[v] = min(low[v], dfn[u]);   //low[v]就取這個點的low值與循環到的點u的dfn[u]的最小值}if (dfn[v] == low[v]) {   //如果發現v這個點的dfn[]和low[]相等,說明這個點是一個強連通分量的“根”。sccnt++;int u;                  //定義u變量,作為棧頂元素do { u = sta.top();        //將u賦值為sta棧的棧頂元素vis[u] = false;       //將u彈出sta.pop();            //同上color[u] = sccnt;     //將u標記為這個強連通分量里的點} while (v != u);       //當v == u之后,結束循環}
}

參考文獻

強連通分量 - OI Wiki

速通Tarjan與強連通分量

全網最最詳細!一文講懂Tarjan算法求強連通分量&縮點 - 淼畔 - 博客園

tarjan算法詳解--關于圖的連通性 & 連通分量 - 知乎

tarjan算法總結 (強連通分量+縮點+割點),看這一篇就夠了~_強連通分量切割-CSDN博客

淺談 tarjan-騰訊云開發者社區-騰訊云

Tarjan-1972.pdf

深入淺出 Tarjan 算法 (一)

60 分鐘搞定圖論中的 Tarjan 算法(一) - 知乎

寫在最后

說實話,我作為初學者,學這個算法的時候挺吃力,看了不少網上的算法書(原因就是把算法書全都忘在學校了QAQ),可能是鄙人智力有限的原因吧。所以我決定自己錄一個視頻,演示一下這個過程。

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

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

相關文章

P1119 災后重建【題解】

P1119 災后重建 題目背景 B 地區在地震過后,所有村莊都造成了一定的損毀,而這場地震卻沒對公路造成什么影響。但是在村莊重建好之前,所有與未重建完成的村莊的公路均無法通車。換句話說,只有連接著兩個重建完成的村莊的公路才能通…

Horse3D引擎研發筆記(二):基于QtOpenGL使用仿Three.js的BufferAttribute結構重構三角形繪制

在Horse3D引擎的研發過程中,我們致力于構建一個高效、靈活且易于擴展的3D圖形引擎。在本篇博客中,我們將詳細記錄如何基于QtOpenGL框架,使用仿Three.js的BufferAttribute結構,重構三角形繪制流程。通過這一過程,我們希…

MCU程序段的分類

程序的下載(燒錄到存儲器中)通常是按照程序文件分段(Code段、RO_data段、RW_data段、ZI_data段)的方式存儲的,但運行時內存的布局會按照程序進程分段(TEXT段、DATA段、BSS段、堆棧段)進行組織。…

綜合項目記錄:自動化備份全網服務器數據平臺

一、項目背景與需求1.1項目概述該項目共分為2個子項目,由環境搭建和實施備份兩部分組成1.2項目總體需求企業內部有一臺web服務器,內部數據很重要,現需要為該web服務器數據做備份,這樣在數據丟失時可以恢復。要求如下:每…

聯合索引全解析:一棵樹,撐起查詢的半邊天

目錄 一、為什么聯合索引是MySQL性能優化的“王牌”? (一)索引的基本結構:從聚簇到非聚簇 1. 聚簇索引(Clustered Index) 2. 非聚簇索引(Secondary Index) (二&…

vue開發的計算機課程頁面

課程信息展示頁面設計與實現我將設計一個美觀且實用的課程信息展示頁面,重點展示計算機網絡應用課程的相關信息。設計思路使用卡片式布局清晰展示課程各模塊信息采用科技感配色方案,符合計算機網絡課程主題添加動畫效果增強用戶體驗響應式設計確保在各種…

MySQL 正則表達式詳細說明

目錄 MySQL 正則表達式詳細說明 1. 基本操作符:REGEXP 和 RLIKE 2. 常用正則表達式模式 3. MySQL 正則表達式函數(MySQL 8.0) 4. 示例查詢 5. 注意事項 6. 總結 MySQL 正則表達式詳細說明 MySQL 支持正則表達式(Regular Ex…

c++之 棧淺析

C之棧淺析 概要 通過可視化游戲梳理棧特點以及棧操作方式. 學習棧的工作原理就像往糖果罐里放糖果和拿糖果一樣簡單! 棧特點 先進后出 技術名詞解釋 LIFO LIFO -> Last In, First Out 后進先出 可視化小游戲 游戲傳送門

C++ 算術函子

在 C 中&#xff0c;算術函子&#xff08;Arithmetic Functors&#xff09; 是標準庫 <functional> 中提供的一組函數對象&#xff0c;用于封裝基本的算術運算&#xff08;如加、減、乘、除等&#xff09;。它們本質上是類模板&#xff0c;重載了 operator()&#xff0c;…

Flutter 事件總線 Event Bus

文章目錄概要核心原理基本使用步驟優點注意事項適用場景小結概要 提示&#xff1a;這里可以添加技術概要 event_bus 是一個常用的第三方庫&#xff0c;用于實現跨組件 / 跨頁面的事件通信&#xff0c;基于發布 - 訂閱模式&#xff08;Publish-Subscribe Pattern&#xff09;工…

數據庫管理系統:入門需要了解的內容

數據庫管理系統&#xff1a;數字化時代的基石 在信息技術飛速發展的今天&#xff0c;我們生活在一個被數據包圍的世界里。從日常使用的社交媒體、電商平臺&#xff0c;到企業運營的核心業務系統&#xff0c;再到政府部門的政務管理&#xff0c;數據無處不在。而數據庫管理系統&…

安裝CST時,報錯問題處理

今天安裝這個軟件的時候&#xff0c;發現一個問題一直處理不了&#xff0c;然后看網上的一些解決方法&#xff0c;最終得到處理&#xff0c;這里就簡單記錄下解決方法。問題&#xff1a;處理方案&#xff1a;1.問題原因&#xff1a;crack中的CST Studio Suite 2022未配置成功。…

分治-快排-215.數組中的第k個最大元素-力扣(LeetCode)

一、題目解析1、需返回排序好的第k個最大元素2、要求時間復雜度為O(N)二、算法原理解法1&#xff1a;堆排序(大根堆) k*O(N)借用大堆的性質&#xff0c;將元素插入到大堆中&#xff0c;按照k輸出堆頂第k個元素解法2&#xff1a;堆排序(小根堆) (N-k)*O(logN)先建k個小堆&#x…

新手向:Python實現圖片轉ASCII藝術

Python實現圖片轉ASCII藝術&#xff1a;從零開始的完整指南Python實現圖片轉ASCII藝術的技術解析ASCII藝術是一種使用字符組合來表現圖像的技術&#xff0c;這種技術源于早期計算機顯示器的圖形限制&#xff0c;如今已成為一種獨特的數字藝術形式。ASCII藝術的應用場景十分廣泛…

6.類與對象(二)

總結 本章寫了封裝、static成員以及代碼塊。 一、封裝 1.封裝的概念 封裝簡單來說就是被密封起來&#xff08;不讓我們看見的東西&#xff09;&#xff0c;即被隱藏。 對于用戶來說&#xff0c;并不需要關心的類&#xff0c;所實現的細節就會被封裝&#xff08;隱藏&#x…

流形折疊與條件機制

1. 為什么要防止流形折疊&#xff08;mode collapse&#xff09; 流形折疊 生成器只學會輸出極少數甚至單一模式&#xff08;mode&#xff09;的樣本&#xff0c;而完全忽略數據分布的多樣性。 后果一句話&#xff1a;“模型看起來生成了很多圖&#xff0c;其實都在重復同一張…

《從零構建大語言模型》學習筆記2,文本數據處理1(以及tiktoken庫無法下載gpt2參數,調用get_encoding時SSL超時的解決方法)

《從零構建大語言模型》學習筆記2&#xff0c;文本數據處理1 文章目錄《從零構建大語言模型》學習筆記2&#xff0c;文本數據處理1前言1、分詞2.將把提取出來的詞元轉換為數字ID3.添加特殊上下文標記4. 字節對編碼&#xff08;以及tiktoken庫無法下載gpt2參數&#xff0c;調用g…

【AI工具】解放雙手,操控瀏覽器的工具對比,來了

&#x1f4d2;前言在github上面&#xff0c;有幾個操作瀏覽器的mcp工具&#xff1a;browser-use / browser-usemicrosoft / playwright-mcpAgentDeskAI / browser-tools-mcphangwin / mcp-chrome想知道他們的區別嗎&#xff0c;想知道那個更適合你嗎&#xff0c;想。。。&#…

Linux 操作系統基礎知識總結

1、操作系統總體介紹 CPU&#xff1a; 就像人的大腦&#xff0c;主要負責相關事情的判斷以及實際處理的機制。 查詢指令&#xff1a; cat /proc/cpuinfo 內存&#xff1a; 大腦中的記憶區塊&#xff0c;將皮膚、眼睛等所收集到的信息記錄起來的地方&#xff0c;以供CPU進行判斷…

cudagraph 本質詳解

理解 CUDA Graph 的本質,關鍵在于理解它解決了什么問題,以及它通過什么機制來解決這個問題。 一、 核心問題:傳統 CUDA 編程的“CPU 瓶頸” 在 CUDA Graph 出現之前,我們通常使用 CUDA Stream 來向 GPU 提交任務。這是一個動態的過程: CPU 作為指揮官:CPU 循環地、逐條…