1. 程式人生 > >uva(11354) 最小瓶頸生成樹+LCA

uva(11354) 最小瓶頸生成樹+LCA

ini ace scanf nbsp pri size esp 最小 bool

求出最小生成樹後lca找最大權即可

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

struct my{
int v;
int next;
int dist;
};

struct node{
int x,y;
int dist;
bool operator <(const node& rhs) const {
return dist<rhs.dist;
}
};
const int maxn=100000+10;
my bian[maxn];
node edge[maxn];
int adj[maxn];
int anc[maxn][20];
int fa[maxn];
int L[maxn];
int fa1;
int m,n;
int maxcost[maxn][20];
int cost[maxn];

void init(){
memset(adj,-1,sizeof(adj));
memset(bian,-1,sizeof(bian));
fa1=0;
memset(fa,0,sizeof(fa));
memset(anc,0,sizeof(anc));
memset(maxcost,0,sizeof(maxcost));
memset(cost,0,sizeof(cost));
}
void myinsert(int u,int v,int d){
bian[++fa1].v=v;
bian[fa1].next=adj[u];
bian[fa1].dist=d;
adj[u]=fa1;
}

void dfs(int u,int f,int dep){
L[u]=dep;
for (int i=adj[u];i!=-1;i=bian[i].next){
int v=bian[i].v;
if(v!=f){
fa[v]=u;
cost[v]=bian[i].dist;
dfs(v,u,dep+1);
}
}
}
void RMQ(){
for (int i=1;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=1;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 getans(int p,int q){
int log;
if(L[p]<L[q]) swap(q,p);
for (log=1;(1<<log)<=L[p];log++);
log--;
int ans=-10000;
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(p==q) 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]);
ans=max(ans,maxcost[q][i]);
p=anc[p][i];
q=anc[q][i];
}
}
ans=max(ans,cost[p]);
ans=max(ans,cost[q]);
return ans;
}

int getfather(int x){
if(x==fa[x]) return x;
else return fa[x]=getfather(fa[x]);
}
int main(){
int kase=0;
while(scanf("%d%d",&n,&m)!=EOF){
init();
int u,v,d;
for (int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&d);
edge[i].x=u;
edge[i].y=v;
edge[i].dist=d;
}
sort(edge+1,edge+m+1);
for (int i=1;i<=n;i++) fa[i]=i;
for (int i=1;i<=m;i++){
int x=edge[i].x;
int y=edge[i].y;
int d=edge[i].dist;
int u=getfather(x);
int v=getfather(y);
if(u!=v){
fa[u]=v;
myinsert(x,y,d);
myinsert(y,x,d);
}
}
dfs(1,-1,0);
RMQ();
int q,l,r;
scanf("%d",&q);
if(++kase!=1) printf("\n");
while(q--){
scanf("%d%d",&l,&r);
printf("%d\n",getans(l,r));
}
}
return 0;
}
/*1 2 3
2 1
3 4 1
4 3*/

uva(11354) 最小瓶頸生成樹+LCA