Test instructions: give you m edge, each edge has a weight, each query only keep the number L to R side, let you divide the picture into two parts
The cost of a scenario is the maximum weight of the current qualifying edge (the qualifying edge refers to a two-segment point in one section), and asks you how to divide it to minimize the cost
Analysis: The current L to R side of the order, from large to small, from the beginning of the large edge, judging whether the current can form a binary map, if you can form a two-part diagram, continue to add edge
If it is not possible to form a binary graph, then the weight of the current edge is the least expensive (not very familiar)
The idea is clear, now we have to solve is how to judge can form a binary graph, there are two, one is 2 dyeing current diagram (definitely timed out)
So there's only one way to take the right and check the set
Take right and check set three step walk
1: Design weights array Relation[i], which represents the relationship between the I node and its root, 0 represents a part, and 1 means that it does not belong to a part
2: Path compression, relation[i]=relation[i]^relation[fa[i]], recursive get and root relationship
3: Merge root node, relation[i]=relation[u]^relation[v]^1;
#include <iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<stack>#include<cstring>#include<algorithm>using namespacestd;Const intn=5e5+5;intFa[n],relation[n];structedge{intU,v,w,id; BOOL operator< (ConstEdge &RHS)Const{ returnW>RHS.W; }}p[n];intFindintx) { if(X==fa[x])returnx; intfx=find (fa[x]); RELATION[X]^=Relation[fa[x]]; returnfa[x]=FX;}BOOLUnion (intUintv) { intFx=find (u), fy=Find (v); if(fx==FY) { if(relation[u]==Relation[v])return false; return true; } FA[FX]=fy; RELATION[FX]=relation[u]^relation[v]^1; return true;}intMain () {intn,m,q; scanf ("%d%d%d",&n,&m,&q); for(intI=1; i<=m;++i) {scanf ("%d%d%d",&p[i].u,&p[i].v,&P[I].W); P[i].id=i; } sort (P+1, p+1+m); while(q--){ intl,r,ret=-1; scanf ("%d%d",&l,&R); for(intI=1; i<=n;++i) fa[i]=i,relation[i]=0; for(intI=1; i<=m;++i) { if(p[i].id<l| | P[I].ID>R)Continue; if(!Union (P[I].U,P[I].V)) {ret=P[I].W; Break;} } printf ("%d\n", ret); } return 0;}
View Code
Codeforces 687D Dividing Kingdom II with weighted and set (DSU)