【kruscal】【最小生成树】【块状树】bzoj3732 Network
2014-10-04 09:06
519 查看
跟去年NOIP某题基本一样。
最小生成树之后,就变成了询问连接两点的路径上的权值最大的边。
倍增LCA、链剖什么的随便搞。
块状树其实也是很简单的,只不过每个点的点权要记录成“连接其与其父节点的边的权值”,然后暴力LCA时不要用LCA的值更新答案了。
最小生成树之后,就变成了询问连接两点的路径上的权值最大的边。
倍增LCA、链剖什么的随便搞。
块状树其实也是很简单的,只不过每个点的点权要记录成“连接其与其父节点的边的权值”,然后暴力LCA时不要用LCA的值更新答案了。
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 15001 int Res,Num;char C,CH[20]; inline int Ge() { Res=0;C='*'; while(C<'0'||C>'9')C=getchar(); while(C>='0'&&C<='9'){Res=Res*10+(C-'0');C=getchar();} return Res; } inline void P(int x) { Num=0;if(!x){putchar('0');puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); putchar('\n'); } struct Edge{int u,v,w;void Read(){u=Ge();v=Ge();w=Ge();}}; bool cmp(const Edge &a,const Edge &b){return a.w<b.w;} Edge edges[maxn<<1]; struct Graph { int v[maxn<<1],first[maxn<<1],next[maxn<<1],w[maxn<<1],en; void AddEdge(const int &a,const int &b) {v[++en]=b;next[en]=first[a];first[a]=en;} void AddEdge(const int &a,const int &b,const int &c) {v[++en]=b;w[en]=c;next[en]=first[a];first[a]=en;} }; Graph G[2]; int fa[maxn],dep[maxn],top[maxn],siz[maxn],sz,maxv[maxn],W[maxn]; int n,m,q,x,y; void makeblock(int cur) { for(int i=G[0].first[cur];i;i=G[0].next[i]) if(G[0].v[i]!=fa[cur]) { dep[G[0].v[i]]=dep[cur]+1; W[G[0].v[i]]=G[0].w[i]; fa[G[0].v[i]]=cur; if(siz[top[cur]]<sz) { siz[top[cur]]++; top[G[0].v[i]]=top[cur]; G[1].AddEdge(cur,G[0].v[i]); } makeblock(G[0].v[i]); } } int rank[maxn],father[maxn]; void init(){for(int i=1;i<=n;i++) father[i]=i;} int findroot(int x) { if(father[x]==x) return x; int rt=findroot(father[x]); father[x]=rt; return rt; } void Union(int U,int V) { if(rank[U]<rank[V]) father[U]=V; else { father[V]=U; if(rank[U]==rank[V]) rank[U]++; } } void dfs(int cur,int Maxnow) { maxv[cur]=Maxnow; for(int i=G[1].first[cur];i;i=G[1].next[i]) dfs(G[1].v[i],max(Maxnow,W[G[1].v[i]])); } int Query_max(int u,int v) { int res=-2147483647; while(u!=v) { if(top[u]==top[v]) { if(dep[u]<dep[v]) swap(u,v); res=max(res,W[u]); u=fa[u]; } else { if(dep[top[u]]<dep[top[v]]) swap(u,v); res=max(res,maxv[u]); u=fa[top[u]]; } } return res; } int main() { n=Ge();m=Ge();q=Ge(); for(int i=1;i<=m;i++) edges[i].Read(); sort(edges+1,edges+m+1,cmp); init(); int cnt=0; for(int i=1;i<=m;i++) { int f1=findroot(edges[i].u),f2=findroot(edges[i].v); if(f1!=f2) { Union(f1,f2); G[0].AddEdge(edges[i].u,edges[i].v,edges[i].w); G[0].AddEdge(edges[i].v,edges[i].u,edges[i].w); cnt++; if(cnt==n-1) break; } } sz=sqrt(n); for(int i=1;i<=n;i++) { top[i]=i; siz[i]=1; } makeblock(1); for(int i=1;i<=n;i++) if(top[i]==i) dfs(i,W[i]); for(int i=1;i<=q;i++) {x=Ge();y=Ge();P(Query_max(x,y));} return 0; }
相关文章推荐
- 【bzoj3732】 network 最小生成树+lca
- BZOJ 3732 Network —— 最小生成树 + 倍增LCA
- 【BZOJ3732】Network 最小生成树+LCA
- BZOJ 3732: Network 最小生成树 倍增
- 【BZOJ】3732 Network 最小生成树+LCA
- 【bzoj3732】Network 最小生成树+倍增LCA
- [BZOJ]3732: Network 最小生成树 LCA
- bzoj3732 Network 最小生成树+LCA+树上倍增
- bzoj 3732: Network (最小生成树+LCA)
- [bzoj3732][最小生成树][lca]Network
- BZOJ 3732: Network(最小生成树+倍增)
- 【枚举】【最小生成树】【kruscal】bzoj3754 Tree之最小方差树
- BZOJ 3732 Network 最小瓶颈路
- BZOJ 3732: Network 最小瓶颈路
- 【kruscal】【最小生成树】【并查集扩展】bzoj3714 [PA2014]Kuglarz
- BZOJ 1083: [SCOI2005]繁忙的都市【Kruscal最小生成树裸题】
- POJ 1861 && ZOJ 1542--Network 【最小生成树 && kruscal && 水题】
- [动态最小生成树 CDQ分治 Kruscal] BZOJ 2001 [Hnoi2010]City 城市建设
- poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)
- 【最小瓶颈生成树】【最小生成树】【kruscal】bzoj1083 [SCOI2005]繁忙的都市