信息學奧賽一本通 1514:【例 2】最大半連通子圖 | 洛谷 P2272 [ZJOI2007] 最大半連通子圖

【題目鏈接】

ybt 1514:【例 2】最大半連通子圖
洛谷 P2272 [ZJOI2007] 最大半連通子圖

【題目考點】

1. 圖論:強連通分量 縮點
2. 圖論:拓撲排序 有向無環圖動規

【解題思路】

對于圖中任意兩頂點u、v,滿足u到vv到u有路徑,該圖就是單向連通圖。本題中的半連通圖,指的就是單向連通圖。
導出圖,指的是選擇頂點之間的所有邊也都必須選擇。
該題求圖中最大的半連通子圖,而且該圖必須是導出圖,也就是選擇頂點數最多的單向連通子圖,而且要同時選擇選出頂點之間所有的邊。
強連通圖一定是單向連通圖,因此可以不用考慮各個強連通分量內部的情況,可以將每個強連通分量視為一個頂點,進行縮點。縮點后,每個頂點(強連通分量)的權值是該強連通分量中頂點數量。
有向無環圖中的單向連通子圖中的頂點一定是圖中一條路徑上的頂點。

反證法:一條路徑上的頂點是 A 1 , A 2 , . . . , A m A_1,A_2,...,A_m A1?,A2?,...,Am?,假設存在頂點 B B B,頂點 B B B和頂點 A 1 , A 2 , . . . , A m A_1,A_2,...,A_m A1?,A2?,...,Am?不會構成一條路徑, A 1 , A 2 , . . . , A m , B A_1,A_2,...,A_m,B A1?,A2?,...,Am?,B的導出圖是一個單向連通圖。

  • 如果頂點 B B B到頂點 A 1 A_1 A1?有邊,則 B , A 1 , A 2 , . . . , A m B,A_1,A_2,...,A_m B,A1?,A2?,...,Am?是一條路徑,不符合假設。而該圖是單向連通圖,如果頂點 B B B到頂點 A 1 A_1 A1?沒有路徑,那么必然存在頂點 A 1 A_1 A1?到頂點 B B B的路徑。
  • 如果頂點 B B B到頂點 A 2 A_2 A2?有邊,則 A 1 , B , A 2 , . . . , A m A_1,B,A_2,...,A_m A1?,B,A2?,...,Am?是一條路徑,不符合假設。而該圖是單向連通圖,如果頂點 B B B到頂點 A 2 A_2 A2?沒有路徑,那么必然存在頂點 A 2 A_2 A2?到頂點 B B B的路徑。
  • 依此類推,頂點 A 1 A_1 A1? A 2 A_2 A2?、…、 A m ? 1 A_{m-1} Am?1?到頂點B都有路徑。
    如果頂點 A m A_m Am?到頂點 B B B有邊,那么 A 1 , A 2 , . . . , A m , B A_1,A_2,...,A_m,B A1?,A2?,...,Am?,B是一條路徑,不符合假設。
    如果頂點 B B B到頂點 A m A_m Am?有邊,那么 A 1 , A 2 , . . . , A m ? 1 , B , A m A_1,A_2,...,A_{m-1},B,A_m A1?,A2?,...,Am?1?,B,Am?是一條路徑,不符合假設。
    因此假設不成立,原命題得證。

在縮點后的圖中,找到點權加和最大的路徑,選擇該路徑上的頂點(強連通分量)在原圖中對應的頂點,以及這些頂點之間的邊構成的子圖,就是原圖中的最大半連通子圖。
縮點后圖中點權加和最大路徑的點權加和,就是原圖中最大半連通子圖包含的頂點數量。
而后還需要求最大半連通子圖的數量,這里可以通過統計點權和為最大路徑點權和的路徑數量,來統計半連通子圖的數量。
兩個連通分量中可能有多條邊相連,縮點后的圖中兩個頂點之間就可能有多條邊,即為重邊。如果縮點后的圖中保留重邊,假設頂點A到頂點B有兩條重邊,那么頂點A到頂點B會被認為有兩條路徑。而本題實際求的是半連通子圖的數量,半連通子圖必須是導出圖,這里選擇了頂點A和頂點B,那么頂點A、B之間的所有邊都必須被選擇,實際只有一個半連通子圖。為了使路徑數量和半連通子圖一致,本題必須
在縮點后的圖中去掉所有重邊,此處可以使用與離散化類似的方法完成對重邊去重。
接下來就是在縮點后的圖中,求有向無環圖中點權加和最大的路徑的點權加和,具體方法見該題:
信息學奧賽一本通 1262:【例9.6】挖地雷 | 洛谷 P2196 [NOIP1996 提高組] 挖地雷
d p [ i ] dp[i] dp[i]表示以頂點i為終點的點權加和最大的路徑的點權加和,在拓撲排序過程中可以求出 d p dp dp數組的值。求 d p dp dp數組最大值的下標為 m x i mxi mxi,頂點 m x i mxi mxi就是點權加和最大的路徑的終點。 d p [ m x i ] dp[mxi] dp[mxi]就是第一個要輸出的解。

為了求出最大半連通子圖的數量,在拓撲排序時還需要進行另一個動規狀態求解:
狀態定義 c n t [ i ] cnt[i] cnt[i]:以頂點i為終點的點權加和為最大值 d p [ m x i ] dp[mxi] dp[mxi]的路徑的數量。
在拓撲排序過程中,在訪問u的鄰接點v時:

  • 如果 d p [ v ] < d p [ u ] + w [ v ] dp[v] < dp[u]+w[v] dp[v]<dp[u]+w[v],( w [ v ] w[v] w[v]是頂點v的點權)。那么要更新 d p [ v ] = d p [ u ] + w [ v ] dp[v]=dp[u]+w[v] dp[v]=dp[u]+w[v],經過頂點u再到頂點v的路徑的點權加和最大,到頂點v點權加和為 d p [ v ] dp[v] dp[v]的路徑數量就是到頂點u點權加為 d p [ u ] dp[u] dp[u]的路徑數量,也就是 c n t [ v ] = c n t [ u ] cnt[v] = cnt[u] cnt[v]=cnt[u]
  • 如果 d p [ v ] = = d p [ u ] + w [ v ] dp[v] == dp[u]+w[v] dp[v]==dp[u]+w[v],那么 d p [ v ] dp[v] dp[v]無需更新,但到達頂點v的點權加和為 d p [ v ] dp[v] dp[v]的路徑增多了,增加了到達頂點u點權加為 d p [ u ] dp[u] dp[u]的路徑數量,即 c n t [ v ] + = c n t [ u ] cnt[v] += cnt[u] cnt[v]+=cnt[u],該題路徑數量需要對 X X X取模,所以增加后應該再模X,寫為cnt[v] = (cnt[v]+cnt[u])%x

【題解代碼】

解法1:圖論 tarjan求強連通分量 縮點 拓撲排序DP
#include<bits/stdc++.h>
using namespace std;
#define N 100005
int n, m, x, dp[N], w[N], cnt[N], cntAns, dfn[N], low[N], ts, scc[N], sn, degIn[N], mxi = 1;
stack<int> stk;
bool inStk[N];
vector<int> edge[N], g[N];//edge:原圖 g:縮點后的圖
void tarjan(int u)
{int t;dfn[u] = low[u] = ++ts;stk.push(u);inStk[u] = true;for(int v : edge[u]){if(dfn[v] == 0){tarjan(v);low[u] = min(low[u], low[v]);}else if(inStk[v])low[u] = min(low[u], dfn[v]);}if(dfn[u] == low[u]){++sn;do{t = stk.top();stk.pop();inStk[t] = false;scc[t] = sn;w[sn]++;//連通分量sn中的頂點數,也就是縮點后頂點sn的權值w[sn]增加1 } while(t != u);}
}
void topoSort()
{queue<int> que;for(int i = 1; i <= sn; ++i){dp[i] = w[i];//dp[i]:縮點后以強連通分量i為終點的點權加和最大的路徑的點權加和cnt[i] = 1;if(degIn[i] == 0)que.push(i); }while(!que.empty()){int u = que.front();que.pop();if(dp[u] > dp[mxi])mxi = u;//mxi:某個以mxi為終點的路徑的點權加和最大 for(int v : g[u]){if(dp[v] < dp[u]+w[v]){dp[v] = dp[u]+w[v];cnt[v] = cnt[u];}else if(dp[v] == dp[u]+w[v])cnt[v] = (cnt[v]+cnt[u])%x;if(--degIn[v] == 0)que.push(v);}}
}
int main()
{int a, b;cin >> n >> m >> x;for(int i = 1; i <= m; ++i){cin >> a >> b;edge[a].push_back(b);}for(int i = 1; i <= n; ++i) if(dfn[i] == 0)tarjan(i);for(int u = 1; u <= n; ++u)for(int v : edge[u]) if(scc[v] != scc[u])g[scc[u]].push_back(scc[v]);for(int i = 1; i <= sn; ++i){sort(g[i].begin(), g[i].end());g[i].erase(unique(g[i].begin(), g[i].end()), g[i].end());//g[i]去重 }for(int u = 1; u <= sn; ++u)for(int v : g[u])degIn[v]++;//degIn[i]:縮點后強連通分量i的入度 topoSort();cout << dp[mxi] << '\n';for(int i = 1; i <= sn; ++i) if(dp[i] == dp[mxi])//所有以i為終點的,點權加和為dp[mxi]的路徑數量加和 cntAns = (cntAns+cnt[i])%x;cout << cntAns;return 0;
}

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

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

相關文章

Android打aar包問題總結

1、moduleA 依賴 moduleB&#xff0c;將moduleA打包成aar時&#xff0c;未包含 moduleB的resources資源&#xff1b; 方法一&#xff1a;將moduleB的資源&#xff0c;手動拷貝一份到moduleA中&#xff1b; 方法二&#xff1a;使用 fat-aar 插件&#xff1b; 2、fat-aar插件使…

【網絡協議】【http】http 簡單介紹

【網絡協議】【http】http 簡單介紹 1 HTTP 頭部 HTTP 是一種請求-響應協議&#xff0c;客戶端向服務器發送請求&#xff0c;服務器返回響應。 1.1 HTTP 狀態碼 狀態碼是服務器返回給客戶端的 三位數字代碼&#xff0c;用于表示請求的執行結果。 狀態碼按照首位數字分類&am…

談談空間復雜度考量,特別是遞歸調用棧空間消耗?

空間復雜度考量是算法設計的核心要素之一&#xff0c;遞歸調用棧的消耗問題在前端領域尤為突出。 以下結合真實開發場景進行深度解析&#xff1a; 一、遞歸調用棧的典型問題 1. 深層次DOM遍歷的陷阱 // 危險操作&#xff1a;遞歸遍歷未知層級的DOM樹 function countDOMNode…

LeetCode算法題(Go語言實現)_16

題目 給定一個二進制數組 nums 和一個整數 k&#xff0c;假設最多可以翻轉 k 個 0 &#xff0c;則返回執行操作后 數組中連續 1 的最大個數 。 一、代碼實現 func longestOnes(nums []int, k int) int {left, zeroCnt, maxLen : 0, 0, 0for right : 0; right < len(nums); …

【數據結構】棧 與【LeetCode】20.有效的括號詳解

目錄 一、棧1、棧的概念及結構2、棧的實現3、初始化棧和銷毀棧4、打印棧的數據5、入棧操作---棧頂6、出棧---棧頂6.1棧是否為空6.2出棧---棧頂 7、取棧頂元素8、獲取棧中有效的元素個數 二、棧的相關練習1、練習2、AC代碼 個人主頁&#xff0c;點這里~ 數據結構專欄&#xff0c…

攻破tensorflow,勇創最佳agent(2)---損失(loss) 準確率(accuracy)問題

實戰播: 怎么判定一個模型好不好,你設置的值對不對? 需要再看幾個值: 例如: model Sequential()for units in model_structure:model.add(Dense(units, activationrelu))model.add(Dropout(train_config.get(dropout_rate, 0.3)))model.add(Dense(1, activationsigmoid)) 他…

pdfh5 pdf

踩坑1&#xff1a; 渲染失敗 &#xff08;1&#xff09;在vue項目中&#xff0c;讀取本地的pdf文件需要放到public下static文件夾中&#xff0c;不能放在別的地方&#xff1b; &#xff08;2&#xff09;引用時&#xff0c;不能使用相對路徑&#xff0c;因為使用public文件下…

6.5 模擬專題:LeetCode 38. 外觀數列

1. 題目鏈接 LeetCode 38. 外觀數列 2. 題目描述 給定一個正整數 n&#xff0c;生成外觀數列的第 n 項。外觀數列的定義如下&#xff1a; 第 1 項為 "1"。第 n 項是對第 n-1 項的描述。例如&#xff0c;第 2 項描述第 1 項&#xff08;"1"&#xff09;為…

什么是具身智能

具身智能&#xff08;Embodied Intelligence&#xff09;是人工智能與機器人學交叉的前沿領域&#xff0c;強調智能體通過身體與環境的動態交互實現自主學習和進化&#xff0c;其核心在于將感知、行動與認知深度融合?。通俗地講&#xff0c;就是機器人或者智能系統在物理環境中…

git命令使用小記(打補丁)

需求&#xff1a;需要從開發分支提取本人提交代碼&#xff0c;然后合并到主分支 一、制作補丁包 mkdir -p patches for commit in $(git log commitA..commitB --author"username" --reverse --prettyformat:"%h"); do …

mapbox基礎,加載popup彈出窗

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??popup 彈出窗 api1.3.1 ??構造函數1.…

C++11--(1)

目錄 1.列表初始化 {}初始化 C98中 C11中 內置置類型和自定義類型 創建對象也適用 std::initializer_list 2.變量類型推導 auto C98 C11 decltype nullptr 3.范圍for循環 4.STL中一些變化 array 1.創建和初始化 2.訪問元素 ?編輯 3.修改操作 4.支持迭代器…

Promise的狀態和方法是什么?

Promise 的狀態和方法 1. Promise 的狀態 一個 Promise 可以處于以下三種狀態之一&#xff1a; - Pending&#xff08;待定&#xff09;&#xff1a;初始狀態&#xff0c;表示異步操作正在進行中&#xff0c;Promise 還沒有被解決或拒絕。 - Fulfilled&#xff08;已完成&…

Windows云服務器支持哪些數據庫管理系統?

Windows云服務器因其良好的兼容性和企業級支持&#xff0c;廣泛用于網站托管、企業管理系統、金融應用、數據分析等場景。在這些應用中&#xff0c;數據庫管理系統(DBMS)起著至關重要的作用。Windows 服務器支持多種數據庫&#xff0c;包括關系型數據庫(SQL)和非關系型數據庫(N…

MongoDB 實際工作中應用場景

博主介紹&#xff1a;?全網粉絲5W&#xff0c;全棧開發工程師&#xff0c;從事多年軟件開發&#xff0c;在大廠呆過。持有軟件中級、六級等證書。可提供微服務項目搭建與畢業項目實戰&#xff0c;博主也曾寫過優秀論文&#xff0c;查重率極低&#xff0c;在這方面有豐富的經驗…

03 相機標定圖像采集

學完本文,您將獲取一下技能: 1:如何提升標定質量,如選擇標定板,標定圖像采集的注意事項, 2:實現標定圖像自動篩選的代碼 3:量產場景如何通過一張圖像來標定相機 為了實現良好的標定效果,以下因素在標定數據采集前必須設置得當。 標定板選擇 標定板尺寸準確材料平…

GitHub美化個人主頁3D圖表顯示配置操作

這個功能主要是用的這個開源倉庫&#xff1a;https://github.com/yoshi389111/github-profile-3d-contrib 想看效果的話&#xff0c;我的個人主頁&#xff1a;https://github.com/Sjj1024 開始操作 1.創建自己的github主頁屬性項目——跟你github用戶名一致即可&#xff0c;…

buu-jarvisoj_fm-好久不見52

格式化字符串漏洞題 x等于4x等于4???????x等于4???????x等于4 可以知道是第11個參數&#xff0c;%11$ 定位到這個位置&#xff0c;然后%n往這個位置寫入4 1.先用pwndbg調試得到偏移量 2.查看獲取x的地址 3.構造ROP鏈&#xff0c;發送連接 from pwn import *# …

AwesomeQt分享3(含源碼)

AwesomeQt 這個項目包含了多個Qt組件的使用示例&#xff0c;旨在展示Qt各種強大功能的實現方式。 源碼分享 github: awesome_Qtgitee: 后續同步 項目進度 QCustomPlot曲線控件示例 支持排序和篩選的列表控件示例 支持排序和篩選的表格控件示例 屬性表示例 Dock窗口示例 自繪…

ubuntu 安裝 g++

文章目錄 前提一、安裝 g1.1 安裝1.2 驗證 前提 安裝 tflite_support 報錯 error: subprocess-exited-with-error RuntimeError: Unsupported compiler -- at least C11 support is needed!一、安裝 g 1.1 安裝 # 安裝編譯工具鏈&#xff08;如g&#xff09;和依賴庫 sudo …