1. 程式人生 > >CCCC訓練練習題-礦工安全生產(求點割集)

CCCC訓練練習題-礦工安全生產(求點割集)

簡單說一下就是給定一個無向聯通圖。要求找到割點(割點:若將該點和關聯該點的邊去掉,圖的連通性發生改變),並把割點刪去。求聯通圖的數量及在每個聯通圖上的某一個點放置一個救生器材的方案數。

我們先要找割點。
找割點的方法其實和找割邊有異曲同工之妙。

從一點開始dfs該圖可以得到一棵dfs樹,設dfs開始的結點為根 rt
在dfs樹中:
1.對於根結點,若它有兩棵或兩棵以上的子樹,那麼根結點一定是割點。
證明:假設根結點不是割點,那麼當挖去根結點後,那麼一定存在兩棵子樹之間是聯通的,那麼這樣的話在dfs樹上它們應該是一棵樹,因此發生矛盾。
2.對於葉結點,一定不是割點。
證明:因為它的度數只有 1

,因此刪去後不改變連通性,所以一定不是割點。
3.對於非根非葉結點 u ,如果它的某棵子樹中有一個點指向 u 的祖先,那麼 u 一定不是割點,否則是割點。
證明:如果它的某棵子樹中有一個點指向 u 的祖先,刪除 u 後,u 的子樹仍然與 u 的祖先有連通性,因此不是割點。否則一定是割點。

對於葉結點和根結點很好處理。對於非葉非根結點,我們可以採用在tarjan找強聯通圖演算法中的 dfn[i]low[i] 來判斷是否有回邊。dfn[i] 儲存的是 i 點在dfs過程中被訪問先後次序的序號, low[i] 儲存的是 i 點及其子樹聯通的 dfn 最小的點。
low[i]>=

dfn[i] ,則表示 i 及其子樹不能訪問到更早的結點,即沒有回邊,那麼 i 就是割點。

當找到所有割點後,進行一次dfs找到連通塊的數量即可。放置的方案數即每個聯通塊點數的乘積。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int dfn[maxn],low[maxn];
bool vis[maxn];
vector<int> adj[maxn];
bool ge[maxn];  //標記該點是否是割點
int id,rt;
void
init(int _rt) { id=0; rt=_rt; for(int i=1;i<maxn;i++) adj[i].clear(); memset(vis,0,sizeof(vis)); memset(ge,0,sizeof(ge)); } void tarjan(int u,int pre) { vis[u]=true; dfn[u]=++id; low[u]=dfn[u]; //初始化dfn和low int cnt=0; if(u!=rt&&adj[u].size()==1) return; //如果該點是葉子結點,不可能是割點,直接返回 for(int i=0;i<adj[u].size();i++) { int v=adj[u][i]; if(v==pre) continue; //無向圖 if(vis[v]) low[u]=min(low[u],dfn[v]); else { cnt++; //cnt記錄dfs樹中點u的子樹數量 tarjan(v,u); low[u]=min(low[u],low[v]); } } //low[u]>=dfn[u]就表示非根節點u的子樹中沒有點訪問到u的祖先,即沒有回邊。 //若是根節點,只要它在dfs樹中有兩個或以上的子樹就是割點。 if((low[u]>=dfn[u]&&u!=rt)||(u==rt&&cnt>=2)) ge[u]=true; } ll ans; ll dfs(int u) { vis[u]=true; ll res=1; for(int i=0;i<adj[u].size();i++) { int v=adj[u][i]; if(!vis[v]&&!ge[v]) res+=dfs(v); } return res; } int main() { int n; while(~scanf("%d",&n)) { if(!n) break; int u,v; int m=0; init(1); for(int i=0;i<n;i++) { scanf("%d%d",&u,&v); m=max(m,max(u,v)); adj[u].push_back(v); adj[v].push_back(u); } tarjan(1,0); ans=1; memset(vis,0,sizeof(vis)); int cnt=0; for(int i=1;i<=m;i++) if(!vis[i]&&!ge[i]) { ans*=dfs(i); cnt++; } printf("%d ",cnt); cout << ans << endl; } return 0; }

相關推薦

CCCC訓練練習題-礦工安全生產

簡單說一下就是給定一個無向聯通圖。要求找到割點(割點:若將該點和關聯該點的邊去掉,圖的連通性發生改變),並把割點刪去。求聯通圖的數量及在每個聯通圖上的某一個點放置一個救生器材的方案數。 我們先要找割點。 找割點的方法其實和找割邊有異曲同工之妙。 從一點

無向圖的演算法

http://blog.csdn.net/xinghongduo/article/details/6202646 黑書上給出了關於求點割集的演算法,但是比較模糊,我查閱了網路上的相關資料,理解了求點割集的過程,寫出如下求點割集的程式碼,並寫了一些簡單的證明. 割點集的定

POJ1523解題報告

SPF Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2082 Accepted: 932 Description Consider the two networks shown below. A

無向圖演算法

黑書上給出了關於求點割集的演算法,但是比較模糊,我查閱了網路上的相關資料,理解了求點割集的過程,寫出如下求點割集的程式碼,並寫了一些簡單的證明. 割點集的定義:如果在連通圖G中去掉某一點後圖不連通,那麼這個點即為G的割點,所有割點的集合即為點割集。 求點割集的方法:利用

poj 1815 Friendship最小

Friendship Time Limit: 2000MS Memory Limit: 20000K Total Submissions: 8465 Accepted: 2370 Description In modern society, each person

熱身訓練-k皇後問題主副對角線計算

tro 變量 線下 with prev span med cell edi Gargari is jealous that his friend Caisa won the game from the previous problem. He wants to prove

Java多線程 —— 線程安全、線程同步、線程間通信含面試題

err 線程等待 共同點 -c java多線 能夠 空間 而不是 不一致 一、線程安全 多個線程在執行同一段代碼的時候,每次的執行結果和單線程執行的結果都是一樣的,不存在執行結果的二義性,就可以稱作是線程安全的。 講到線程安全問題,其實是指多線程環境下對共享資源的訪問可能會

poj2631 ?Roads in the North樹的直徑

cst num ted style positive con inpu eache memset Roads in the North Time Limit: 1000MS Memory Limit: 65536K Total Su

js三級聯動思路更好

選擇 all sta acid 加載 res code sele spl 首先看下界面: 說到select聯動,我就想到用ajax獲取數據加載出來。 然後就開始寫,select被改變的時候,觸發ajax去後臺找數據,數據要自己下級分類數據和當前選擇分類的商品數據。 寫完之

Exponentiation高精度冪

alt args wan 一位 shu input h+ plain pri Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 175340 Accepted

POJ1474:Video Surveillance多邊形的核

require 分享圖片 less exists post 比較 req 技術分享 edge A friend of yours has taken the job of security officer at the Star-Buy Company, a famous

歐幾裏得算法最大公約數

include spa end IV ios sin int 計算 name 1 //求兩個數的最大公約數 2 #include<iostream> 3 using namespace std; 4 int f(int m,int n) 5 { 6

hdu 1166 敵兵布陣【線段樹】給定區間和

tar 每次 pre 研究 amp sin des ++ 無奈 題目鏈接:https://vjudge.net/contest/182746#problem/B

題解報告:hdu 2036 改革春風吹滿地 多邊形的面積

處理 names esc rec hdu 告訴 輸入數據 col fix Problem Description “ 改革春風吹滿地,不會AC沒關系;實在不行回老家,還有一畝三分地。謝謝!(樂隊奏樂)”話說部分學生心態極好,每天就知道遊戲,這次考試如此簡單的題目,也是雲裏霧

第四階段組隊訓練賽第六場 題源:UKIEPC2017

col radi gre network == led build period tro A: Alien Sunset 題目描述 Following tremendous advances in space flight control software and equa

Web 安全之內容安全策略Content-Security-Policy,CSP詳解

pid eba elf safe 數據 信息 java php 我們 1.CSP 簡介 內容安全策略(Content Security Policy,簡稱CSP)是一種以可信白名單作機制,來限制網站是否可以包含某些來源內容,緩解廣泛的內容註入漏洞,比如 XSS。 簡單來說,

算法學習——貪心算法之刪數字最大值

size 算法學習 末尾 最小 條件 求最大值 sca 位數 技術 算法描述 在給定的n位數字,刪除其中的k位數字( k < n),使得最後的n-k為數字為最大值(原次序不變) 算法思路 考慮到是要移出數字,我們使用鏈表設計此算法較為方便,鏈表可以直接移出某個位

poj 1269 Intersecting Lines 兩直線交點

題目連結:poj 1269 題意:給出n個詢問,每次給兩條邊,有三種不同的結果可以輸出,1,平行不共線,2,平行且共線,3,相交併求出交點 題解:模板題,注意一點的是,判斷兩直線平行時用叉積去判斷,不要簡單的直接用斜率公式去判斷,可能會出現誤差。 程式碼如下: #include&

【模板】歸併排序+逆序對

沒有網址qwq 沒有oj 翻樹狀陣列看到求逆序對先複習一下歸併求逆序對qwq 逆序對真是個神奇的東西啊QAQ 純屬隨手一打隨手一貼quq 1 #include<cstdio> 2 #include<iostream> 3 using namespace std

Q - Castle Walls POJ - 1794 逆序對

Q - Castle Walls  POJ - 1794  Background  In medieval times, knights commanded big armies of peasants. When they had to storm a cas