http://blog.csdn.net/loi_yzs/article/details/52938283
正解:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXV=10100;
const int MAXE=101000;
int first[MAXV],nxt[MAXE<<1];
int dis[MAXV],deep[MAXV],fa[MAXV],f[MAXV];
int n,m,q,tot;
bool used[MAXV];
struct edge
{
int from,to,cost;
}es[MAXE<<1],c[MAXE<<1];
bool cmp(edge a,edge b)
{
return a.cost<b.cost;
}
void init()
{
memset(first,-1,sizeof(first));
for(int i=1;i<=n;i++) f[i]=i;
tot=0;
}
void build(int f,int t,int d)
{
es[++tot]=(edge){f,t,d};
nxt[tot]=first[f];
first[f]=tot;
}
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
void dfs(int s)
{
used[s]=1;
for(int i=first[s];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(!used[v])
{
fa[v]=s;
deep[v]=deep[s]+1;
dis[v]=es[i].cost;
dfs(v);
}
}
}
int lca(int x,int y)//利用lca的想法
{
int maxx=0;//利用lca找路径上的最大值
if(deep[x]>deep[y]) swap(x,y);
while(deep[x]!=deep[y])
{
if(dis[y]>maxx) maxx=dis[y];
y=fa[y];
}
while(x!=y)
{
if(dis[x]>maxx) maxx=dis[x];
if(dis[y]>maxx) maxx=dis[y];
x=fa[x];
y=fa[y];
}
return maxx;
}
int main()
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
scanf("%d%d%d",&c[i].from,&c[i].to,&c[i].cost);
sort(c+1,c+m+1,cmp);//最小生成树
for(int i=1;i<=m;i++)
{
int u=find(c[i].from);
int v=find(c[i].to);
if(u!=v)
{
f[u]=v;
build(c[i].from,c[i].to,c[i].cost);
build(c[i].to,c[i].from,c[i].cost);
}
}
dfs(1);//建树
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",lca(u,v));
}
return 0;
}//没什么好说的╮(╯▽╰)╭
查不出来区别….wa
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,fa[10005],cnt,tot,head[10005],fath[10005],q,x,y,dep[10005],dis[10005];
bool used[10005];
struct Edge{
int from,to,cost,next;
bool flag;
}e[200005],ex[200005];
bool cmp(Edge x,Edge y)
{
return x.cost<y.cost ;
}
int find(int x)
{
if(x==fa[x]) return fa[x];
else return fa[x]=find(fa[x]);
}
void addedge(int fn,int tn,int ct)
{
tot++;
ex[tot].from=fn;//这里要新建一个ex[]
ex[tot].to=tn;
ex[tot].cost=ct;
ex[tot].next=head[fn];
head[fn]=tot;
}
void mst()
{
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
if(find(e[i].from) !=find(e[i].to))
{
cnt++;
fa[e[i].to]=e[i].from;//这个fa并查集用
addedge(e[i].from,e[i].to,e[i].cost);
addedge(e[i].to,e[i].from,e[i].cost);
}
if(cnt==n-1)//只有这么多边了
break;
}
}
void dfs(int u)
{
used[u]=1;
for(int i=head[u];i>0;i=ex[i].next)
{
int v=ex[i].to;
if(!used[v])
{
fath[v]=u;//这个fath单纯的记录父亲
dep[v]=dep[u]+1;
dis[v]=ex[i].cost;//
dfs(v);//
}
}
}
int lca(int x,int y)
{
int mx=0;
if(dep[x]>dep[y]) swap(x,y);
while(dep[x]!=dep[y])
{
if(dis[y]>mx) mx=dis[y];
y=fath[y];//一个一个往上爬的... /
}
while(x!=y)//爬到相同高度再同时爬
{
if(dis[x]>mx) mx=dis[x];
if(dis[y]>mx) mx=dis[y];
x=fath[x];
y=fath[y];
}
return mx;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].cost);
}
sort(e+1,e+m+1,cmp);
mst();
// cout<<endl;
// for(int i=1;i<=tot;i++)
// cout<<e[i].from<<","<<e[i].to<<endl;
// cout<<endl;
dfs(1);
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
}