使用演算法:堆優化 \(prim\) , \(lca\) 。
大樣例題目鏈結
共有 \(n\) 個點,有 \(m\) 條邊來連線這些點,每條邊有權值。有 \(q\) 條類似於 \(u\)
\(v\) 詢問,求一條從 \(u\) 到 \(v\) 的路徑使得路徑上的最小權值最大,求這個最大值。若不存在從 \(u\) 到 \(v\) 的路徑,則輸出 \(-1\) 。
先求該圖的最大生成樹,因為需要使得該路徑上的最小值最大,而這條路徑就是最小生成樹的中兩點的簡單路徑(最大生成樹盡量取最大的邊)。
故而,查詢時的路徑確定了,那麼現在就是求這條路徑的最小值了。
樹上的距離操作離不開 \(lca\) 。
假設查詢 \(2\) 和 \(4\) 之間的距離最小值。那麼它們之間的簡單路徑為 \(2->1->3->4\) ,可以分為兩段:\(s->lca\) 和 \(lca->t\) 。這就是兩條鏈,可以使用倍增求解。兩條鏈的最小值一起來求最小值即可。
查詢兩個點是否在路徑很簡單,就是判斷他們是否在乙個連通塊,直接在處理 \(prim\) 時一起求解即可。
#include #include #include #include using namespace std;
#define inf 0x3f3f3f3f
#define swap(a, b) (a ^= b ^= a ^= b)
#define min(a, b) ((a) < (b) ? (a) : (b))
void quick_read(int &n)
while(c >= '0' && c <= '9')
n *= op;
}const int maxn = 1e4 + 5;
const int maxm = 40;
struct node
node(int t, int d)
friend bool operator < (node x, node y)
};int fa[maxn][maxm], minn[maxn][maxm];
int de[maxn];
vectorv[maxn];
priority_queueq;
bool vis[maxn];
int dis[maxn], belong[maxn];
int ans, tot;
int n, m, t;
int lca(int x, int y)
} return fa[x][0];
}int climb(int x, int y)
return res;
}void prim(int s)
} }}void query() }}
void build()
}void read()
}int main()
NOIP 2013 提高組 貨車運輸
a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。第一行有兩個用乙個空格隔開的整數 n,m,表示 a 國有 n 座城市和 m 條道路。接下來 m ...
NOIP2013提高組 貨車運輸
noip2013 提高組 day1 試題。a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。第一行有兩個用乙個空格隔開的整數 n m,表示 a 國...
NOIp 2013 提高組 火柴排隊 題解
問題描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自 排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 i 1n ai b i 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴...