這個題調了一天。。
傳送門讀完題目之後我們不難想出這個題是個tarjan縮點問題,因為盡量多的經過草場,所以一號點所在的強連通分量裡左右的點都是不需要在進行走逆向邊,所能到達的。
然後問題就落在怎麼處理我們走這一次逆向邊上。
仔細看題目要求,題目要求我們必須從一號點出發,最後回到一號點。所以我想到了建乙個逆向的圖,虛擬出cnt + 1 , cnt+2,cnt+3.....n+cnt號點,建乙個逆向圖(用進行縮點之後的點集重新構造),因為我們求出進過草場最多是多少,所以我們將強連通分量中有多少個點在縮點中記錄下來(num[i]:表示第ii個強連通分量中有多少個點),將它作為邊權。
最後我們只要從1號點所在的強連通分量開始,跑一邊最長路就好了,最後輸出從1號點到我們虛擬出來的1 + cnt號點就好了。
#include #include#include
#include
#include
using
namespace
std;
const
int maxn = 2e5 + 5
;inline
intread()
while(ch >= '
0' && ch <= '9')
return x *f;
}int
n,m,x,y;
inthead[maxn],tot,head2[maxn],tot2;
intans;
struct
edgeedge[maxn
<< 1],edge2[maxn << 1
]; void add(int u,int
v)void add_edge(int u,int
v)int
dfn[maxn],low[maxn],ind;
intbelong[maxn],num[maxn],cnt,stack[maxn],top;
bool
ins[maxn];
void tarjan(int
x) }
int k = 0
;
if(dfn[x] ==low[x])
while(k !=x);
}}int
dis[maxn];
bool
vis[maxn];
void spfa(int
s) }}}
}int
main()
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++)
num[i + cnt] =num[i];
for(int i=1;i<=m;i++)
if(belong[edge[i].from] !=belong[edge[i].to])
spfa(belong[
1]);
printf(
"%d\n
",dis[belong[1] +cnt]);
return0;
}
洛谷P5049 洛谷P5022 題解 旅行
原題 資料加強版 加強版 參考你谷題解 終於調過了 又是一如既往的申必錯誤 noi plus石錘了 原題的資料允許我們 o n 2 暴力斷邊,但是加強版的資料達到了 n log n 級別,我們必須在斷邊這一環節尋求更好的解法。考慮我們進入環後在何處回溯 根據繼續走環走到的點分類 設當前已經從 b 走...
洛谷練習P2279 P1346
2020年,人類在火星上建立了乙個龐大的基地群,總共有n個基地。起初為了節約材料,人類只修建了n 1條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地a到基地b至少要經過d條道路的話,我們稱基地a到基地b的距離為d。由於火星上非常乾燥,經常引發火...
洛谷 P1396 營救
題目描述 咚咚咚 查水表!原來是查水表來了,現在 找這麼熱心上門的查表員啊!小明感動的熱淚盈眶,開起了門 媽媽下班回家,街坊鄰居說小明被一群陌生人強行押上了警車!媽媽豐富的經驗告訴她小明被帶到了t區,而自己在s區。該市有m條大道連線n個區,一條大道將兩個區相連線,每個大道有乙個擁擠度。小明的媽媽雖然...