Topic: Given an n-point M edge of the undirected connected graph. K-Times ask the minimum of the longest edge in all paths between two points
LCT's naked question!
First, maintain a dynamic minimum spanning tree, and then delete the most weighted edge on the path between two points each time you increase the edge. In the last query, the maximum weight on the X-to-y chain can be obtained directly. The water is exploding!
!
。
。。
Okay, the real trick is to see http://blog.csdn.net/popoqqq/article/details/39755703.
I'm just bored with the lct of the water. 0.0
Tle for a long time ...
Because there is edge right for the edge of 0 I did not update ...
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 15010# Define INF 2147483647using namespace std;struct edge{int x, y, Z;} E[m<<1];struct abcd{ABCD *fa,*ls,*rs; int Num,maxedge; BOOL Rev_mark; ABCD (int x); void Reverse (); void Push_up (); void Push_down ();} *null=new ABCD (0), *TREE[M],*EDGES[M<<1];ABCD:: ABCD (int x) {fa=ls=rs=null; Num=maxedge=x; rev_mark=0;} void ABCD:: Reverse () {rev_mark^=1; Swap (LS,RS);} void ABCD:: Push_up () {int maxnum=-1; if (e[ls->maxedge].z>maxnum) maxnum=e[ls->maxedge].z,maxedge=ls->maxedge; if (e[rs->maxedge].z>maxnum) maxnum=e[rs->maxedge].z,maxedge=rs->maxedge; if (e[num].z>maxnum) maxedge=num; }void ABCD:: Push_down () {if (fa->ls==this| | Fa->rs==this) Fa->push_down (); if (Rev_mark) {ls->reverse (); Rs->reverse (); rev_mark=0; }}void Zig (ABCD *x) {ABCD *y=x->fa; y->ls=x->rs; x->rs->fa=y; x->rs=y; x->fa=y->fa; if (Y==y->fa->ls) y->fa->ls=x; else if (y==y->fa->rs) y->fa->rs=x; y->fa=x; Y->push_up ();} void Zag (ABCD *x) {ABCD *y=x->fa; y->rs=x->ls; x->ls->fa=y; x->ls=y; x->fa=y->fa; if (Y==y->fa->ls) y->fa->ls=x; else if (y==y->fa->rs) y->fa->rs=x; y->fa=x; Y->push_up ();} void Splay (ABCD *x) {x->push_down (); while (x->fa->ls==x| | x->fa->rs==x) {ABCD *y=x->fa,*z=y->fa; if (X==y->ls) {if (y==z->ls) Zig (y); Zig (x); } else {if (y==z->rs) Zag (y); Zag (x); }} x->push_up ();} void Access (ABCD *x) {ABCD *y=null; while (X!=null) {splay (x); x->rs=y; X->push_up(); Y=x; x=x->fa; }}abcd* find_root (ABCD *x) {while (x->fa!=null) x=x->fa; return x;} void Move_to_root (ABCD *x) {Access (x); Splay (x); X->reverse ();} void Link (ABCD *x,abcd *y) {move_to_root (x); X->fa=y;} void Cut (ABCD *x,abcd *y) {move_to_root (x); Access (y); Splay (y); x->fa=null; y->ls=null; Y->push_up ();} int Query (ABCD *x,abcd *y) {move_to_root (x); Access (y); Splay (y); return Y->maxedge;} int n,m,k;void Insert (ABCD *X,ABCD *y,int pos) {if (E[POS].X==E[POS].Y) return; if (Find_root (x) ==find_root (y)) {int temp=query (x, y); if (e[temp].z<=e[pos].z) return; Cut (edges[temp],tree[e[temp].x]); Cut (Edges[temp],tree[e[temp].y]); }//if (Find_root (x) ==find_root (y))//printf ("%d\n", 1/0); Link (X,edges[pos]); Link (Y,edges[pos]);} int main () {int i,x,y; cin>>n>>m>>k; for (i=1;i<=n;i++) tree[i]=new ABCD (0); for (i=1;i<=m;i++) edges[i]=new abcd (i); for (i=1;i<=m;i++) {scanf ("%d%d%d", &e[i].x,&e[i].y,&e[i].z); Insert (Tree[e[i].x],tree[e[i].y],i); } for (i=1;i<=k;i++) {scanf ("%d%d", &x,&y); printf ("%d\n", E[query (Tree[x],tree[y])].z); }}
Bzoj 3732 Network Link-cut-tree (I'm serious!!)