中位數(DP 二分)

2021-10-02 23:18:42 字數 2666 閱讀 5559

單點時限: 10.0 sec

記憶體限制: 256 mb

「你的地圖是一張白紙,所以即使想決定目的地,也不知道路在**。」

qq 小方最近在自學圖論。他突然想出了乙個有趣的問題:

一張由 n 個點,m 條邊構成的有向無環圖。每個點有點權 ai。qq 小方想知道所有起點為 1 ,終點為 n 的路徑中最大的中位數是多少。

一條路徑的中位數指的是:一條路徑有 n 個點,將這 n 個點的權值從小到大排序後,排在位置 ⌊n2⌋+1 上的權值。

輸入格式

第 1 行輸入兩個正整數 n,m (1≤n≤106,1≤m≤106),表示結點數量和邊的數量。

第 2 行輸入 n 個由空格隔開的整數 ai (0≤ai≤109),表示點權。

接下來 m 行,每行輸入兩個整數 x,y (1≤x,y≤n),表示有一條 x 指向 y 的單向邊,保證給出的圖是聯通的,可能存在重邊。

輸出格式

輸出一行包含乙個整數,表示最大的中位數。如果不存在任何一條起點為 1 ,終點為 n 的路徑,則輸出 −1 。

樣例input

5 51 2 3 4 5

1 22 3

3 52 4

4 5output

4思路:

初看思路:看到此題,首先想到的方法是dfs,記錄每條頂點1~n的路徑,對路徑的上的點權排序,求中位數,最後選擇所有中位數中的最大值。這個方法是最容易想到的,但是某些資料超時了未能ac

//dag------- 鄰接表版 

#include

#include

#include

#include

using

namespace std;

const

int maxv =

1000005

;const

int inf =

1000000000

;int n,m;

bool vis[maxv]=;

int dp[maxv]

;//dp[i] 從點i到n的路徑中,最大的點權之和

int w[maxv]

, w2[maxv]

;vector<

int> adj[maxv]

;intdp(

int x)

return dp[x];}

bool

check

(int mid)

memset

(vis,

false

,sizeof

(vis));

fill

(dp+

1,dp+

1+n,

-inf)

;//設定邊界

dp[n]

= w2[n]

; vis[n]

=true

;returndp(

1)>=0;

}int

main()

//讀入鄰接表

int x,y;

for(

int i=

0;i)int low =

0, high = inf, mid;

while

(low<=high)

else

}printf

("%d\n"

, high)

;return0;

} `//dag -----------------逆鄰接表版

#include

#include

#include

#include

using

namespace std;

const

int maxv =

1000005

;const

int inf =

1000000000

;int n,m;

//n:頂點數 m:邊數

bool vis[maxv]=;

int dp[maxv]

;//dp[i]: 從點i到n的路徑中,最大的點權之和

int w[maxv]

, w2[maxv]

;//記錄點權

vector<

int> adj[maxv]

;//逆鄰接表

intdp

(int mid,

int x)

return dp[x];}

bool

check

(int mid)

fill

(dp+

1,dp+n+1,

-inf)

; dp[1]

= w2[1]

; vis[1]

=true

;return

dp(mid, n)

>=0;

}int

main()

int x,y;

for(

int i=

0;i)//二分檢測

int low =

0, high = inf, mid;

while

(low<=high)

else

}printf

("%d\n"

, high)

;return0;

} `

樹狀陣列 二分 中位數之中位數

給出乙個長度為 n 的序列 a 首先求出其所有區間的中位數,將這些中位數構成的集合記為 s 求 s 中所有數的中位數。此題中位數指 有 n 個數,第 left lfloor frac right rfloor 1 個數即為中位數。資料範圍 1 leq n leq 10 5,1 leq a i leq...

最大中位數 二分

給定乙個由 n n n 個整數組成的陣列 a a a,其中 n n n 為奇數。你可以對其進行以下操作 選擇陣列中的乙個元素 例如 a i a i 將其增加 1 1ai 1 你最多可以進行 k k 次操作,並希望該陣列的中位數能夠盡可能大。奇數長度的陣列的中位數是陣列以非降序排序後的中間元素。例如,...

每日演算法 二分,中位數

題目 4.尋找兩個正序陣列的中位數 給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出這兩個正序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則...