縮點其實算tarjan求強連通分量的乙個應用吧.
由於乙個強連通分量內部可以互通.所以可以將其縮成乙個點.把圖變成dag.然後就可以跑一跑dp啥的了.
模板題目1:洛谷p3387
題目大意:
給你乙個有向連通圖.每個點有點權.問你找出一條路徑使得點權值最大.每個點和每個邊能夠經過多次.但是只算一次點權.
題目思路:
縮點,然後dag上跑最長路即可.
#include
using
namespace std;
const
int maxn =
1e4+4;
vector<
int> e[maxn]
;int dfn[maxn]
, low[maxn]
, vis[maxn]
, a[maxn]
, val[maxn]
;stack<
int> s;
int cnt =
0, tot =0;
// tot 用來給強連通分量標號,用來縮點建邊
int id[maxn]
;vector<
int> new_e[maxn]
;void tarjan (
int u)
else
if(vis[v])}
if(dfn[u]
== low[u])}
}int dp[maxn]
;int dfs (
int u)
return dp[u]
= ans + val[u];}
intmain()
for(
int i =
1; i <= m ; i++
)for
(int i =
1; i <= n ; i++
)for
(int i =
1; i <= n ; i++)}
}// cout << tot << endl;
memset
(dp ,-1
,sizeof dp)
;int ans =0;
for(
int i =
1; i <= tot ; i++
) cout << ans << endl;
return0;
}
模板題目2:洛谷p2341-受歡迎的牛
題目大意:
給你一張n點m邊的有向連通圖.問你有多少個點是其他所有點能夠達到的.
n ,m
≤1e5
n,m \leq 1e5
n,m≤1e
5 題目思路:
縮點的乙個應用。稍微需要一些推理。
考慮同乙個強連通分量之間可以互通。那麼對於有若干個強連通分量的圖:當且僅當圖中只有乙個出度為0的強連通分量時,存在答案。答案即為這個分量的大小
解釋:假設乙個強連通分量s有出度。設到達的分量為t。那麼t是無法到達s的。
因為如果t能夠達到s的話,t,s就能夠互達了。t,s就是同乙個連通分量了。與假設衝突了. 所以只有出度為0的強連通分量是其他所有點能夠互通的。
而如果有多個出度為0的分量。則它們之間是不能互通的。也不存在答案。
分析到這裡,直接套tarjan演算法縮點求出度即可
#include
using
namespace std;
const
int maxn =
1e4+5;
vector<
int> e[maxn]
;int dfn[maxn]
, low[maxn]
, du[maxn]
, vis[maxn]
, id[maxn]
, sz[maxn]
, cnt , tot;
stack<
int> s;
void tarjan (
int u)
else
if(vis[v])}
if(dfn[u]
== low[u])}
}int
main()
for(
int i =
1; i <= n ; i++
)for
(int i =
1; i <= n ; i++)}
}int cnt =
0, res =0;
for(
int i =
1; i <= tot ; i++)}
if(cnt >=
2) cout <<
"0"<< endl;
else cout << res << endl;
return0;
}
Tarjan縮點 洛谷P2341
傳送門 這題很簡單,不知道為什麼是提高組的題.主要思路就是先tarjan縮點,然後在dag上找出度為0的點,如果只有乙個出度為0的點,那麼這個點就是的大小就是受歡迎的牛的數目。如果有兩個及以上個點的出度為0,那麼不存在明星牛。下面是 include using namespace std const...
洛谷 縮點 tarjan演算法模板題
目錄 題目描述 輸入格式 輸出格式 思路 給定乙個 n個點 m 條邊有向圖,每個點有乙個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。允許多次經過一條邊或者乙個點,但是,重複經過的點,權值只計算一次。第一行兩個正整數 n,m 第二行 n個整數,依次代表點權 第三至 m 2行,...
洛谷 P2656 採蘑菇(Tarjan縮點,dp)
對於每一條路,很顯然只有兩種情況,一種是走一次,一種是走無限次,而第二種情況的條件是這條邊在乙個環中。所以先用tarjan縮點,每個點的權值更新為這個環上所有邊一直摘的蘑菇數的和。然後跑一邊既有邊權也有點權的dag上的dp即可。資料有鍋,後四個點答案有誤,用double存實際上錯了,但是標程是dou...