思路 : 這道題是一道tarjan + 最長路的題。首先,我們用tarjan把每個強連通分量縮成乙個點,並記錄那個強連通分量的點權和(因為當那個人走進乙個強連通分量後那個強連通分量中的所有money都會被他拿走(繞一圈不就完了?)),然後我們化點權為邊權,再以起點所在的強連通分量跑最長路,最後就能計算出從起點所在的強連通分量到任意乙個終點所在的強連通分量的最長距離了(最大money值),輸出的是取從起點所在的強連通分量到任意乙個終點所在的強連通分量的最大值。
細節問題 :
code:
1 #include 2#define inf 0x3f3f3f3f
3using
namespace
std;
4 stack < int >pru;
5int n, m, p, head[500001], q[500001], col[500001], color, dfn[500001], low[500001], s, e[500001], sum[500001], z, num, vis[500001], dis[500001], ans;//
變數太多懶得解釋,意會一下吧。。。
6struct node//
存邊 7
stu[500001
];10 queue < node > g;//
用於臨時存放邊
11 inline void add(int x, int y, int
z)12
19 inline void tarjan(int u)//
tarjan演算法,這裡用於縮點
2032
else
if(!col[k])
3336}37
if(dfn[u] ==low[u])
3847
pru.pop();48}
49return;50
}51 inline void spfa(int s)//
求最短路模板spfa
5275}76
}77}78
return;79
}80 inline void init()//
初始化
8189 num = 0;90
return;91
}92 inline void
add_edge()
93);//
要建負邊權(這樣可以把最長路轉化為最短路)
103}
104}
105}
106 init();//
初始化
107while(!g.empty())//
初始化完再存邊
108113
return
;114
}115
signed main()
116123
for(register int i = 1; i <= n; ++i)
124127 scanf("
%d %d
", &s, &p);
128for(register int i = 1; i <= p; ++i)
129132
for(register int i = 1; i <= n; ++i)
133138
}139 add_edge();//
建邊 140 spfa(col[s]);//
從起點所在的強連通分量中開始
141for(register int i = 1; i <= p; ++i)
142145 printf("%d"
, ans);
146return0;
147 }
洛谷P3627 APIO2009 搶掠計畫
題目大意 給你一張 n n leqslant5 times10 5 個點 m m leqslant5 times10 5 條邊的有向圖,有點權,給你起點和一些可能的終點。問從起點開始,到任意乙個終點經過的點權和的最大值是多少。題解 先把有向圖縮點,然後從起點跑最長路,對每個終點取個最大值即可 卡點 ...
P3627 APIO2009 搶掠計畫
題目描述 siruseri 城中的道路都是單向的。不同的道路由路口連線。按照法律的規定,在每個路口都設立了乙個 siruseri 銀行的 atm 取款機。令人奇怪的是,siruseri 的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。banditji 計畫實施 siruseri 有史以來最驚天動地...
P3627 APIO2009 搶掠計畫
p3627 apio2009 搶掠計畫 tarjan縮點 最短 最長 路 顯然的縮點.在縮點時,順便維護每個強連通分量的總權值 縮完點按照慣例建個新圖 然後跑一遍spfa最長路,列舉每個有酒吧的點即可 但是我為什麼會搞dp呢.dp 81pts 這麼顯然的最長路,為什麼會搞dp呢.怕不是被dp題毒害了...