您的位置:首页 > 其它

【BZOJ】【P3732】【Network】【题解】【最小生成树+倍增】

2014-09-30 17:43 323 查看
传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3732

出noip裸题有意思么……

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1.5e4+10;
struct edge{
int u,v,w;
bool operator<(const edge &E)const{
return w<E.w;
}
};
edge edges[50001];
vector<edge>G[maxn];
int n,m,q;
int fa[maxn],dep[maxn];
int p[maxn][17],vis[maxn];
int maxx[maxn][17];
int find(int x){
if(fa[x]!=x)return fa[x]=find(fa[x]);return x;
}
void dfs(int u){
vis[u]=1;
for(int i=1;i<=16;i++){
if(dep[u]<(1<<i))break;
p[u][i]=p[p[u][i-1]][i-1];
maxx[u][i]=max(maxx[u][i-1],maxx[p[u][i-1]][i-1]);
}for(int i=0;i<G[u].size();i++){
edge e=G[u][i];
if(!vis[e.v]){
p[e.v][0]=u;
maxx[e.v][0]=e.w;
dep[e.v]=dep[u]+1;
dfs(e.v);
}
}
}
int Qmax(int u,int v){
if(find(u)!=find(v))return -1;
if(dep[u]<dep[v])swap(u,v);
int d=dep[u]-dep[v];
int ans=INT_MIN;
for(int i=0;i<=16;i++){
if((1<<i)&d){
ans=max(ans,maxx[u][i]);
u=p[u][i];
}
}if(u==v)return ans;
for(int i=16;i>=0;i--){
if(p[u][i]!=p[v][i]){
ans=max(ans,max(maxx[u][i],maxx[v][i]));
u=p[u][i];v=p[v][i];
}
}ans=max(ans,max(maxx[u][0],maxx[v][0]));
return ans;
}
int main(){
scanf("%d%d",&n,&m);
scanf("%d",&q);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].w);
sort(edges+1,edges+1+m);
for(int i=1;i<=m;i++){
if(find(edges[i].u)!=find(edges[i].v)){
fa[find(edges[i].u)]=find(edges[i].v);
G[edges[i].u].push_back(edges[i]);
G[edges[i].v].push_back((edge){edges[i].v,edges[i].u,edges[i].w});
}
}
memset(maxx,0x7f,sizeof maxx);
for(int i=1;i<=n;i++)if(!vis[i])
dfs(i);
while(q--){
int u,v;scanf("%d%d",&u,&v);
printf("%d\n",Qmax(u,v));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj