題解 搶掠計畫 強聯通分量縮點學習筆記

2022-09-19 03:42:13 字數 1335 閱讀 5159

solution:

首先這是一張有向圖,點有點權,且給定乙個起點,給定多個終點,詢問從起點出發,在任意乙個終點結束,所經過的點權和最大值

如果對於任意一條邊,把它終點的點權作為該邊的邊權,那麼只需從起點出發跑乙個最長路就可以了

但問題是,邊權都為正,一旦出現環,就無法跑最長路了

注意到一句話:「他可以經過同一路口或道路任意多次。但只要他搶劫過某個 atm 機後,該 atm 機裡面就不會再有錢了。」,這說明每個點最多只能經過一次。

這道題我們可以用強聯通分量和縮點解決

強聯通圖:對於乙個有向圖,若任意兩個節點都可以互相到達,那麼稱該圖為強連通圖

強聯通分量:對於乙個有向圖,它的「極大強聯通子圖」為強聯通分量。乙個圖可能有多個強聯通分量

縮點:對於圖的每個強聯通分量,在原圖中用乙個點表示,所形成的新圖一定是有向無環圖

於是我們就可以求出圖的強聯通分量,並縮點,再跑乙個拓撲排序或spfa,因為沒有環,所以可以跑最長路

注意縮點時要把原圖中的點的資料集中到縮完後的點上,具體的集中方法根據題目要求靈活處理

#includeusing namespace std;

//#define int long long

inline int read()

while(ch>='0'&&ch<='9')

return x*w;

}const int n=5e5+100;

int n,m,a[n],s,p,bar[n],low[n],dfn[n],c[n],d[n],barc[n],valc[n],deg[n];

int totc,tot,stk[n],ins[n],top;

vectorv[n];

struct nodee[n];

int head[n],cnt;

void add(int x,int y,int z)

void tarjan(int x)//求強聯通分量模板

} while(q.size())

} }}signed main()

for(int i=1;i<=n;++i) a[i]=read();

s=read();p=read();

for(int i=1;i<=p;++i)

for(int i=1;i<=n;++i)

for(int i=1;i<=n;++i)

for(int i=1;i<=n;++i)

}// spfa();

topu();

int ans=0;

for(int i=1;i<=totc;++i)

} cout

}

targin 強聯通分量 縮點

在乙個有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強聯通。如果所有頂點都強聯通,稱g是乙個強聯通圖。非強聯通圖有向圖的極大強聯通子圖,稱為強聯通分量。深度優先搜尋。dfn i 節點i被搜尋到的次序編號。low i i或i的子樹能夠追溯到的最早的節點的次序號。low i min dfn i ...

強連通分量 搶掠計畫

siruseri城中的道路都是單向的。不同的道路由路口連線。按照法律的規定,在每個路口都設立了乙個siruseri銀行的atm取款機。令人奇怪的是,siruseri的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。banditji計畫實施siruseri有史以來最驚天動地的atm搶劫。他將從市中心出...

演算法 強連通分量縮點

有時對於乙個有向圖我們及其渴望將其變為乙個有向無環圖,這樣我們就要用到強連通分量縮點了。洛谷3387 縮點 題目背景 縮點 dp。題目描述 給定乙個 n個點 m條邊有向圖,每個點有乙個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。允許多次經過一條邊或者乙個點,但是,重複經過的...