先保存代码,以后继续学。Lca也可以做
入门学习博客:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4384
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson L,mid,o<<1
#define rson mid + 1,R,o<<1|1
using namespace std;
const int N = 510005;
int fa[N],dep[N],son[N],siz[N];
int top[N],w[N],tot;
int maxv[N];
int minv[N],sum[N],sets[N];
int _min,_sum,_max;
int cnt = 0;
int p[N];
int finf(int x){return p[x] = x == p[x]?x:finf(p[x]);}
struct Edge2
{
int u,v,w;
bool operator < (const Edge2 & e)const{
return w > e.w;
}
}a[N];
struct Edge
{
int from,to,next,w;
Edge(){}
}edge[N];
int eh[N];
void init(){
cnt = tot = 0 ;
memset(eh,-1,sizeof(eh));
memset(siz,0,sizeof(siz));
memset(son,0,sizeof(son));
memset(top,0,sizeof(top));
memset(minv,0x3f,sizeof(minv));
}
void add(int u,int v,int c)
{
edge[cnt].from = u;
edge[cnt].to = v;
edge[cnt].w = c;
edge[cnt].next = eh[u];
eh[u] = cnt++;
}
void addedge(int u,int v,int c)
{
add(u,v,c);
add(v,u,c);
}
void dfs_1(int cur,int d)
{
dep[cur] = d;
int cnum = 1,pre = -1;
for(int i = eh[cur];i != -1; i = edge[i].next){
int v = edge[i].to;
if(v == fa[cur]) continue;
fa[v] = cur;
dfs_1(v,d + 1);
if(pre < siz[v]) son[cur] = v,pre = siz[v];
cnum += siz[v];
}
siz[cur] = cnum;
}
void dfs_2(int cur)
{
w[cur] = ++tot;
if(!top[cur]) top[cur] = cur;
if(son[cur]) {
top[son[cur]] = top[cur];
dfs_2(son[cur]);
}
for(int i = eh[cur]; i != -1; i = edge[i].next){
int v = edge[i].to;
if(v == fa[cur] || v == son[cur]) continue;
dfs_2(v);
}
}
void update(int L,int R,int o,int p,int v)
{
if(L == R) minv[o] = v;
else{
int mid = (R + L) >> 1;
if(p <= mid) update(lson,p,v);
else update(rson,p,v);
minv[o] = min(minv[o<<1],minv[o <<1|1]);
}
}
int query(int L,int R,int o,int x,int y)
{
if(x <= L && R <= y){
return minv[o];
}
int mid = (L + R) >> 1;
int minn = 0x3f3f3f3f;
if(x <= mid) minn = min(minn,query(lson,x,y));
if(y > mid) minn = min(minn,query(rson,x,y));
return minn;
}
int find(int va,int vb)
{
int f1 = top[va], f2 = top[vb], tmp = 0x3f3f3f3f;
while (f1 != f2){
if (dep[f1] < dep[f2]){swap(f1, f2); swap(va, vb);}
tmp = min(tmp, query(1,tot,1,w[f1],w[va]));
va = fa[f1]; f1 = top[va];
}
if (va == vb) return tmp;
if (dep[va] > dep[vb]) swap(va, vb);
return min(tmp, query(1, tot, 1, w[son[va]], w[vb]));
}
void kruscal(int n,int m)
{
for(int i = 0; i <= n; ++i)p[i] = i;
for(int i = 0; i < m; ++i){
Edge2 e = a[i];
int x = finf(e.u),y = finf(e.v);
if(x == y) continue;
p[x] = y;
addedge(e.u,e.v,e.w);
}
}
int main()
{
int u,v,w1,n,m,s;
while(~scanf("%d%d%d",&n,&m,&s)){
for(int i = 0; i < m; ++i){
scanf("%d%d%d",&u,&v,&w1);
a[i].u = u,a[i].v = v;a[i].w = w1;
}
init();
sort(a,a + m);
kruscal(n,m);
dfs_1(1,1);
dfs_2(1);
for(int i = 0; i < cnt; ++i){
Edge e = edge[i];
if(dep[e.from] > dep[e.to]) continue;
update(1,tot,1,w[e.to],e.w);
}
while(s--){
scanf("%d%d",&u,&v);
printf("%d\n",find(u,v));
}
}
return 0;
}