寫這個題的時候,其實已經手擼出LCA——樹鏈剖分算法,
下面給出一段我的LCAn模板,說真的真的很好寫不能更好寫了,大家可以看看別的算法再來看我的實現,個人覺得寫的還不錯(一定要先有了解不然可能看不懂)
int dis[maxn], htop[maxn], sz[maxn], dep[maxn], hson[maxn], dist[maxn], fa[maxn];
//sz[],當前節點孩子數目,htop[]當前節點所處重鏈,dep[]當前節點的深度,hson[]是這個節點的孩子中sz[]數組最大的節點,dist[]是從此節點到根的距離
//fa[]他爹
void dfs1(int u){
sz[u] = 1;
for(int i = begin[u]; i; i = next[i])
if(to[i] != fa[u]){
int v = to[i];
fa[v] = u;
dep[v] = dep[u] + 1;
dis[v] = dis[u] + w[i];
dfs1(v);
if(sz[v] > sz[hson[u]])hson[u] = v;
sz[u] += sz[v];
}
}
void dfs2(int u, int v){
htop[u] = v;
for(int i = begin[u]; i; i = next[i]){
int j = to[i];
if(htop[j])continue;
if(hson[u] == j)dfs2(j, v);
else dfs2(j, j);
}
}
int lca(int a,int b){
while(htop[a] != htop[b]){
if(dep[htop[a]] < dep[htop[b]]){int t;t=a;a=b;b=t;}
a=fa[htop[a]];
}
return dep[a] < dep[b]?a : b;
}
這是模板,雖然下面的實現用不到這麼多,但我還是寫上吧;大家可以做參考,再寫一個博客太累了。。。。。
接着到本題,其實很好理解,就是先用最大生成樹,什麼?怎麼求->直接sort貪心拿最大值,所求的路徑必定是最大生成樹上的一條,否則不符合最大生成樹定義
寫這個博客主要是犯了很都比的錯誤,鄰接表寫錯一個字母啊,sort排邊寫成n點的個數吐了;
還有就是開始寫的時候寫到查找的時候,發現順序被打亂離線不好求,於是想參考網上的代碼;
但是居然沒有一個人寫tarjan
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 40010
#define M 100010
using namespace std;
int n, m;
int start[N], nxt[N], to[N], ee, f[N];
int dep[N], dist[N],fa[N],w[N];
struct truck{
int x,y,w;
}e[M];
bool cmp(truck a, truck b){return a.w>b.w;}
void read(int &x){
char c=getchar();
x=0;
while(c<'0' || c>'9')c=getchar();
while(c>='0' && c<= '9'){
x=x*10+c-'0';
c=getchar();
}
}
bool vis[N];
void dfs(int u)
{
vis[u]=true;
for(int i = start[u]; i; i=nxt[i])
if(!vis[to[i]])
{
fa[to[i]]=u;
dist[to[i]]=w[i];
dep[to[i]]=dep[u] + 1;
dfs(to[i]);
}
}
int check(int t1,int t2){
int mn1 = 0x7f7f7f7f, mn2 = 0x7f7f7f7f;
if(dep[t1] < dep[t2]) swap(t1, t2);
while(dep[t1] > dep[t2])
{
mn1=min(mn1, dist[t1]);
t1=fa[t1];
}
while(t1!=t2)
{
mn1=min(mn1, dist[t1]);
t1=fa[t1];
mn2=min(mn2, dist[t2]);
t2=fa[t2];
}
return min(mn1, mn2);
}
void add(int x, int y,int z){
to[++ee]=y;
nxt[ee]=start[x];
start[x]=ee;
w[ee]=z;
}
int find(int x){
if(f[x]!=x)return f[x]=find(f[x]);
return f[x];
}
int main(){
read(n);read(m);
for(int i=1; i<=m; ++i)read(e[i].x),read(e[i].y),read(e[i].w);
for(int i=1; i<=n; ++i)f[i]=i;
sort(e+1,e+m+1,cmp);
int tot=0;
for(int i=1; i<=m; ++i){
int a=find(e[i].x), b=find(e[i].y);
if(a!=b){
f[a]=b;
add(e[i].x,e[i].y,e[i].w);
add(e[i].y,e[i].x,e[i].w);
tot ++;
if(tot==n-1)break;
}
}
for(int i=1; i<=n; ++i)if(!vis[i])dfs(i);
int q, x, y;
read(q);
for(int i=1; i<=q; ++i){
read(x);read(y);
if(find(x)!=find(y)){puts("-1");continue;}
printf("%d\n",check(x,y));
}
return 0;
}
/*
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
*/