Topic: Given a non-connected graph of N-point M-Edge, K-Times asks for the minimum value of the longest edge of 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 join the edge! The last query directly to the X-y chain to the maximum weight can be! The water exploded!!
。。。 Okay, the real trick is to see http://blog.csdn.net/popoqqq/article/details/39755703.
I'm just bored with the water, LCT. 0.0
Tle for a long time ... Because there is edge right for 0 side 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!!)