社区讨论
[萌新求助] 倍增+LCA
P1967[NOIP 2013 提高组] 货车运输参与者 6已保存回复 15
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 15 条
- 当前快照
- 1 份
- 快照标识符
- @mi7up9a8
- 此快照首次捕获于
- 2025/11/21 03:55 4 个月前
- 此快照最后确认于
- 2025/11/21 04:04 4 个月前
TLE #13 #17 (O2可过)
哪里能优化一下的啊
CPP#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define inf 2147483647
using namespace std;
const int maxn = 100000 + 10;
int n,m,q;
int father[maxn];
int head[maxn],cnt,a,b,c;
int f[maxn][20],val[maxn][20],dep[maxn];
struct data{
int from,to,val;
} maps[maxn];
struct node{
int next,to,val;
} tree[maxn];
void init();
void kruskal();
int lca(int,int);
void dfs(int,int);
int getFather(int);
bool cmp(data,data);
void add(int,int,int);
int main(){
scanf("%d%d",&n,&m);
for (int i = 0; i < m; i++)
scanf("%d%d%d",&maps[i].from,&maps[i].to,&maps[i].val);
init();
kruskal();
for (int i = 1; i <= n; i++)
if (father[i] == i)
dfs(i,0);
scanf("%d",&q);
for (int i = 0; i < q; i++){
scanf("%d%d",&a,&b);
if (getFather(a) == getFather(b))
printf("%d\n",lca(a,b));
else printf("-1\n");
}
return 0;
}
void init(){
for (int i = 1; i <= n; i++) father[i] = i;
memset(head,-1,sizeof(head));
memset(val,-1,sizeof(val));
}
void kruskal(){
int done = 0;
sort(maps,maps+m,cmp);
for (int i = 0; i < m; i++){
int u = maps[i].from;
int v = maps[i].to;
if (getFather(u) == getFather(v)) continue;
father[getFather(v)] = getFather(u);
add(v,u,maps[i].val); add(u,v,maps[i].val);
if (++done == n - 1) break;
}
}
int lca(int x, int y){
int minn = inf;
if (dep[x] > dep[y]) swap(x,y);
for (int i = 20; i >= 0; i--){
if ((1<<i) > dep[y]) continue;
if (dep[f[y][i]] >= dep[x]){
minn = min(minn,val[y][i]);
y = f[y][i];
if (x == y) return minn;
}
}
for (int i = 20; i >= 0; i--){
if ((1<<i) > dep[x]) continue;
if (f[x][i] != f[y][i]){
minn = min(minn,min(val[x][i],val[y][i]));
x = f[x][i];
y = f[y][i];
}
}
return min(minn,min(val[x][0],val[y][0]));
}
void dfs(int id, int p){
dep[id] = dep[p] + 1; f[id][0] = p;
for (int i = 1; (1<<i) <= dep[id]; i++)
f[id][i] = f[f[id][i-1]][i-1],
val[id][i] = min(val[f[id][i-1]][i-1],val[id][i-1]);
for (int i = head[id]; ~i; i = tree[i].next)
if (tree[i].to != p)
val[tree[i].to][0] = tree[i].val,
dfs(tree[i].to,id);
}
int getFather(int id){
return id==father[id] ? id:getFather(father[id]);
}
bool cmp(data a,data b){
return a.val > b.val;
}
void add(int a, int b, int c){
tree[cnt].val = c;
tree[cnt].to = b;
tree[cnt].next = head[a];
head[a] = cnt++;
}
回复
共 15 条回复,欢迎继续交流。
正在加载回复...