傳送門
演算法:tarjan & dp
顯然縮點後的圖是乙個dag
dag上搞dp是基本操作啊
按拓撲序搞一波dp就好了
設 f[ i ] 表示從起點搶劫到 dag 上的點 i 時能得到的最多的錢
那麼 f[ i ] = max( f [ i ] , f[ j ] + sval[ i ]) ( j 有一條邊指向 i , sval[ i ] 表示dag上點 i 的錢數)
至於 tarjan 的具體操作看**,這裡不再贅述
測了一波,自己的dp比spfa快個100ms(都開了o2)
一些與本題無關的話:
其實真正意義的縮點還要把重複的邊給去掉(縮點後可能兩個塊之間有多條邊)
可以把邊給離散化,然後去重
具體操作:
struct縮點但是對於本題根本不需要去除重複邊edge
e[n];
//存邊
int cnt3,du[n];//
cnt存總邊數,du存入度
int firr[n],fromm[n],too[n],cntt;//
鏈式前向星存dag
inline void add2(int &a,int &b)//
給dag連邊
inline
bool cmp(const edge &x,const edge &y)
}sort(e+1,e+cnt3+1,cmp);//
排序for(int i=1;i<=cnt3;i++)
if(e[i].b!=e[i-1].b||e[i].a!=e[i-1].a)//
因為排好序了,所以可以這樣判斷重複的邊
add2(e[i].a,e[i].b),du[e[i].b]++;//
如果沒重複就加入dag
}
要也可以,但是sort多乙個log,反而更慢...
廢話結束上**
#include#include#include
#include
#include
#include
using
namespace
std;
inline
intread()
while(ch>='
0'&&ch<='9'
)
return x*f;
}const
int n=5e5+7
;int
n,m,k,sta;
intval[n];
int fir[n],from
[n],to[n],cnt;
inline
void add(int &a,int &b)//
給原圖連邊
//幾乎就是tarjan的模板
intdfn[n],low[n],be[n],sval[n],st[n],cnt2,dfs_clock,_top;
bool bar[n],bar[n];//
bar表示原圖的酒吧,bar表示dag上的酒吧
void tarjan(int
x)
if(dfn[x]==low[x])
if(bar[st[_top]]) bar[cnt2]=1
; sval[cnt2]+=val[st[_top]];
be[st[_top--]]=cnt2;
}}int du[n];//
存入度,dp要用
int firr[n],fromm[n],too[n],cntt;//
存dag
inline void add2(int &a,int &b)//
連dag的邊
void build()//
沒有去重邊的dag建構函式
}}int
f[n],ans;
queue
q;void dp()//
按拓撲序的dp
}for(int i=1;i<=cnt2;i++) if(bar[i]) ans=max(ans,f[i]);//
在有酒吧的塊內找乙個錢最多的塊
}int
main()
for(int i=1;i<=n;i++) a=read(),val[i]=a;
sta=read() ;k=read();
for(int i=1;i<=k;i++) a=read(),bar[a]=1
; tarjan(sta);
//只要從起點tarjan就好了,其他的反正也到不了
build();//
構造dag
dp();
printf("%d
",ans);
return0;
}
P3627 APIO2009 搶掠計畫
題目描述 siruseri 城中的道路都是單向的。不同的道路由路口連線。按照法律的規定,在每個路口都設立了乙個 siruseri 銀行的 atm 取款機。令人奇怪的是,siruseri 的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。banditji 計畫實施 siruseri 有史以來最驚天動地...
P3627 APIO2009 搶掠計畫
p3627 apio2009 搶掠計畫 tarjan縮點 最短 最長 路 顯然的縮點.在縮點時,順便維護每個強連通分量的總權值 縮完點按照慣例建個新圖 然後跑一遍spfa最長路,列舉每個有酒吧的點即可 但是我為什麼會搞dp呢.dp 81pts 這麼顯然的最長路,為什麼會搞dp呢.怕不是被dp題毒害了...
洛谷P3627 APIO2009 搶掠計畫
題目大意 給你一張 n n leqslant5 times10 5 個點 m m leqslant5 times10 5 條邊的有向圖,有點權,給你起點和一些可能的終點。問從起點開始,到任意乙個終點經過的點權和的最大值是多少。題解 先把有向圖縮點,然後從起點跑最長路,對每個終點取個最大值即可 卡點 ...