bzoj 1924 所駝門王的寶藏

2022-06-01 15:24:13 字數 2746 閱讀 9573

題目大意:

有乙個r*c的矩陣,上面有n個點有寶藏

每個有寶藏的點上都有傳送門

傳送門有三種:第一種可以傳到該行任意乙個有寶藏的點,第二種可以傳到該列任意乙個有寶藏的點,第三種可以傳到周圍的八連塊上有寶藏的點

現在你可以在任意乙個有寶藏的點開始,求你最多可以經過多少個不同的藏寶點

每個藏寶點可以多次進入,每個傳送門可以多次使用

思路:很容易可以看出這個矩陣並沒有什麼卵用

而此題的關鍵在於如何建圖,建圖所用陣列見注釋

建完之後,可以使用tarjan演算法之一的求強連通分量

因為對於每個強連通分量,只要到達任意乙個點,就可以到達其餘所有點

然後我們縮點,把每個強連通分量都縮為乙個點

再重新建圖

這樣圖就會變成dag,然後求一下最長鏈並統計每乙個強連通分量內有幾個點就好了

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include

11 #include12

#define inf 2147483611

13#define ll long long

14#define maxn 101001

15using

namespace

std;

16 inline int

read()

1721

while(isdigit(ch))

22return x*f;23}

24int dx[8]=,dy[8]=;//

八連塊用陣列

25 map m[10*maxn];//

記錄每個位置是否有藏寶點,因為陣列開不下只能用map

26 vector vr[10*maxn],vc[10*maxn];//

記錄每行每列所有藏寶點,用vector方便記錄

27int

n,r,c;

28int x[maxn],y[maxn];//

記錄每個點的橫縱座標

29short t[maxn];//

記錄每個點的傳送門種類

30int to[10*maxn],next[10*maxn],first[maxn],cnt;//

第一次圖用鄰接表

31int to0[10*maxn],next0[10*maxn],first0[maxn];//

dag第二次圖用鄰接表

32int low[maxn],dfn[maxn],stp,scc,now,st[maxn],top;//

tarjan用陣列

33//

scc記錄一共有多少強連通分量,stp記錄步數,st、top記錄棧

34int num[maxn],blg[maxn];//

num記錄每個強連通分量中有多少個點,blg記錄每個點屬於那個強連通分量

35int deep[maxn];//

求最長鏈用,記錄每個強連通分量能延伸的最長長度

36int

ans;

37bool vis[maxn];//

第一次為tarjan用,第二次求最長鏈用

38void add(int u,int v)//

第一次建圖

3943

void add(int u,int v) //

第二次建圖

44void build()//

第一次建圖

4551

for(int j=0;j)

5256}57

for(int i=1;i<=c;i++)//

同一列,方法同上

5861

for(int j=0;j)

6266}67

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

八連塊

68if(t[i]==3)69

for(int j=0;j<8;j++) if(m[x[i]+dx[j]][y[i]+dy[j]]) add(i,m[x[i]+dx[j]][y[i]+dy[j]]);70}

71void tarjan(int x)//

tarjan求強連通分量

72//

在棧外且未被訪問過

78else

if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);//

在棧內

79if(low[x]==dfn[x])

8087}88

}89void build()//

第二次建圖

9095

void dp(int x)//

求最長鏈

96103 deep[x]+=num[x];

104 ans=max(ans,deep[x]);

105}

106int

main()

107116

build();

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

118if(!dfn[i]) tarjan(i);

119 cnt=0

;120

build();

121for(int i=1;i<=scc;i++)

122if(!vis[i]) dp(i);

123 printf("%d"

,ans);

124 }

view code

BZOJ1924 所駝門王的寶藏 KEY

題目傳送門 這道題苟了我好久,因為鍊錶的記憶體問題,之後再細講。首先這是一道tarjan dag上dp的題目。有三種門,對於每種門可以和其他門相連。即連邊。使用鍊錶快速查詢連邊。建完圖後可以進行tarjan縮點。然後做一遍dag上dp就好了。記搜 然後因為建圖時會有很多條邊,而行列最多只有10000...

BZOJ 1924 所駝門王的寶藏 縮點 最短路

給出乙個1e6 1e6 1e6 1e6 1e6 1e 6的矩形,矩形中有三種傳送門,分別是傳送這一行的任意乙個傳送門,或者傳送到這一列的任意乙個傳送門,或者是傳送附近8 88個位置的任意乙個傳送門。然後你可以選擇並且只能選擇從任何乙個傳送門進入,從任何乙個傳送門出來。求經過最多的點的個數是多少。預處...

BZOJ 1924 Sdoi2010 所駝門的寶藏

time limit 5 sec memory limit 128 mb submit 1380 solved 603 submit status discuss 第一行給出三個正整數 n,r,c。以下 n 行,每行給出一扇傳送門的資訊,包含三個正整數xi,yi,ti,表示該傳送門設在位於第 xi行...