lh的简单图论 http://10.64.70.166/problem/1112 lh的简单图论 Description 众所周知,集训队的lh同学txdy,有一天他在写着代码,突然哼起了 rap r a p,哟,哟哟,你看这个碗它又大又圆,就像这个题
lh的简单图论
http://10.64.70.166/problem/1112
lh的简单图论Description
众所周知,集训队的lh同学txdy,有一天他在写着代码,突然哼起了raprap,哟,哟哟,你看这个碗它又大又圆,就像这个题它又短又难,skrskr,skrskr。
lhlh在着手解决一个图论的问题:
已知有一个nn个点的无向图,图中有mm条边,每条边的权值为w_iwi?。
lhlh想知道,他从点aa走到点bb,所走的最长的边长最小值是多少?
Input
第一行输入三个正整数n,m,qn,m,q,分别表示有nn个点mm条边和qq次询问。
接下来mm行,每行有三个数分别为u_iui?、v_ivi?、w_iwi?表示从点uu到点vv有一条路径边长为ww。
接下来qq行,每行有两个数aa,bb,表示lhlh想知道他从aa走到bb所走的最长的边长的最小值。
Output
输出qq行,每行一个正整数,表示他从点aa走到点bb,所走的最长的边长最小值是多少。
Sample Input 1
6 6 8 1 2 5 2 3 4 3 4 3 1 4 8 2 5 7 4 6 2 1 2 1 3 1 4 2 3 2 4 5 1 6 2 6 1
Sample Output 1
5 5 5 4 4 7 4 5
Hint
1≤n≤15000
1≤M≤30000
1≤wi?≤1000000000
1≤q≤20000
这个题目就是比较典型的图转树,这个好像就是UVA的11354
你要用最小生成树把图转变成树,然后再用LCA处理这棵树
#include <cstring> #include <cstdlib> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <queue> #include <iostream> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 3e4 + 100; int dp[maxn][30]; ll gw[maxn][30]; int deep[maxn]; int n, m, q, N; struct node { int from,to; ll dist; node(int from=0,int to=0,ll dist=0):from(from),to(to),dist(dist){} }exa[maxn]; vector<node>vec[maxn]; int f[maxn]; int findx(int x) { return f[x] == x ? x : f[x] = findx(f[x]); } void unite(int x,int y) { x = findx(x); y = findx(y); if (x == y) return; f[x] = y; } bool same(int x,int y) { return findx(x) == findx(y); } bool cmp(node a,node b) { return a.dist < b.dist; } void dfs(int s) { for(int i=1;i<=N;i++) { dp[s][i] = dp[dp[s][i - 1]][i - 1]; gw[s][i] = max(gw[s][i - 1], gw[dp[s][i - 1]][i - 1]); } int len = vec[s].size(); for(int i=0;i<len;i++) { node e = vec[s][i]; if(e.to!=dp[s][0]) { deep[e.to] = deep[s] + 1; dp[e.to][0] = s; gw[e.to][0] = e.dist; dfs(e.to); } } } ll LCA(int x,int y) { if (x == y) return 0; if (deep[x] > deep[y]) swap(x, y); ll ans = 0; for(int i=N;i>=0;i--)//抬到同一高度 { if(deep[x]<deep[y]&&deep[dp[y][i]]>=deep[x]) { ans = max(ans, gw[y][i]); y = dp[y][i]; } } for(int i=N;i>=0;i--)//一起往上走 { if(dp[x][i]!=dp[y][i]) { ans = max(ans, gw[x][i]); ans = max(ans, gw[y][i]); x = dp[x][i]; y = dp[y][i]; } } if(x!=y)//最后一步 { ans = max(ans, gw[x][0]); ans = max(ans, gw[y][0]); } return ans; } int main() { cin >> n >> m >> q; for(int i=1;i<=m;i++) { int a, b; ll w; cin >> a >> b >> w; exa[i] = node(a, b, w); } for (int i = 1; i <= n; i++) f[i] = i; sort(exa + 1, exa + 1 + m, cmp); for(int i=1;i<=m;i++) { int x = exa[i].from, y = exa[i].to; if (same(x, y)) continue; unite(x,y); vec[x].push_back(node(x, y, exa[i].dist)); vec[y].push_back(node(y, x, exa[i].dist)); } N = (log(n + 0.0)) / log(2.0); deep[1] = 0; dfs(1); for(int i=1;i<=q;i++) { int x, y; cin >> x >> y; ll ans = LCA(x, y); cout << ans << endl; } return 0; }