您的位置:首页 > 其它

uva 11354最小生成树瓶颈路(lca算法实现)(rmq在多校二中有一道题)

2014-03-12 22:10 393 查看
/*uva 11865
最小生成树瓶颈路
本来写了个BFS预判和LA5713一样,还线性优化了存储,结果还是T了,
不得不用LCA了,cry瞎
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define maxn 100100
#define maxm 200100
#define inf 999999999
using namespace std;
int n,m,ques;
vector<int>G[maxn];
vector<int>D[maxn];
int nextint(){int x;scanf("%d",&x);return x;}
struct Edge{
int u,v,d;
bool operator<(const Edge& x ) const{
return d<x.d;
}
}E[maxm],edges[maxm];
int p[maxn];
int findx(int x){
if (x==p[x]) return x;else return p[x]=findx(p[x]);
}
void init()
{
for(int i=0;i<m;i++){
int u,v,d;
u=nextint();v=nextint();d=nextint();
u--,v--;
E[i]=(Edge){u,v,d};
}
sort(E,E+m);

for(int i=0;i<=n;i++) G[i].clear();
for(int i=0;i<=n;i++) D[i].clear();
}
void MST()
{
for(int i=0;i<=n;i++) p[i]=i;

for(int i=0;i<m;i++){
int u=E[i].u,v=E[i].v,d=E[i].d;
int pu=findx(u),pv=findx(v);
if (pu==pv) continue;
p[pu]=pv;
G[u].push_back(v);D[u].push_back(d);
G[v].push_back(u);D[v].push_back(d);
}
}

int root,fa[maxn],cost[maxn],L[maxn];
int anc[maxn][20],maxcost[maxn][20];
struct Node{
int u,l;
};
void dfs(int u,int f,int deep)//预处理fa,L,cost
{
L[u]=deep;
for(int i=0;i<G[u].size();i++){
int d=D[u][i];
int v=G[u][i];
if (v!=f){
fa[v]=u;
cost[v]=d;
dfs(v,u,deep+1);
}
}
}
void preprocess(){
memset(maxcost,0,sizeof(maxcost));
memset(anc,0,sizeof(anc));
for(int i=0;i<n;i++){
anc[i][0]=fa[i];maxcost[i][0]=cost[i];
for(int j=1;(1<<j)<n;j++) anc[i][j]=-1;
}
for(int j=1;(1<<j)<n;j++)
for(int i=0;i<n;i++)
if (anc[i][j-1]!=-1){
int a=anc[i][j-1];
anc[i][j]=anc[a][j-1];
maxcost[i][j]=max(maxcost[i][j-1],maxcost[a][j-1]);
}
}

int query(int p,int q){
int tmp,log,i;
if(L[p]<L[q]) swap(p,q);
for(log = 1;(1<<log)<=L[p];log++);log--;

int ans=-inf;
for(int i=log;i>=0;i--){
if (L[p]-(1<<i)>=L[q]){ans=max(ans,maxcost[p][i]);p=anc[p][i];}
}
if (q==p) return ans;

for(int i=log;i>=0;i--){
if (anc[p][i]!=-1 && anc[p][i]!=anc[q][i]){
ans=max(ans,maxcost[p][i]);p=anc[p][i];
ans=max(ans,maxcost[q][i]);q=anc[q][i];
}
}
ans=max(ans,cost[p]);
ans=max(ans,cost[q]);
return ans;
}
int cas=0;
int main()
{
while(cin>>n>>m && n>0){
if (cas>0) printf("\n");
init();MST();
dfs(0,-1,0);
preprocess();
int Q;
cin>>Q;
while(Q--){
int p,q;
p=nextint();q=nextint();
printf("%d\n",query(p-1,q-1));//注意:节点必须从0开始编号
}
cas++;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: