WZJ的数据结构(负二十一) |
难度级别:C; 运行时间限制:5000ms; 运行空间限制:262144KB; 代码长度限制:2000000B |
试题描述 |
请你实现一个数据结构,完成这样的功能: 给你一个N个点的图,初始状态无边。 每次加入一条双向边(u,v,w),若加入后没有构成一棵生成树,输出“Not Yet”,否则输出当前最小生成树的权值。 |
输入 |
第一行两个正整数N,M。表示有N个点M个操作。 接下来M行每行三个正整数u,v,w。 |
输出 |
每次加入一条双向边(u,v,w),若加入后没有构成一棵生成树,输出“Not Yet”,否则输出当前最小生成树的权值。 |
输入示例 |
4 6 1 2 10 2 3 10 3 4 10 2 2 1 1 3 2 2 4 3 |
输出示例 |
Not Yet Not Yet 30 30 22 15 |
其他说明 |
1<=N<=100000 1<=M<=500000 1<=ui,vi<=N 1<=wi<=1000 |
题解:这才是真正的动态MST呀
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(‘ ‘) 8 #define ENT putchar(‘\n‘) 9 #define CH for(int d=0;d<=1;d++) if(ch[d]) 10 using namespace std; 11 const int maxn=300000+10,maxm=1500000+10,inf=-1u>>1; 12 struct node{ 13 node*fa,*ch[2],*mx;int x;bool rev; 14 node(){fa=ch[0]=ch[1]=NULL;mx=this;x=0;rev=false;} 15 void revt(){swap(ch[0],ch[1]);rev^=1;return;} 16 void update(){mx=this;CH{if(mx->x<ch[d]->mx->x)mx=ch[d]->mx;}return;} 17 void down(){if(rev){CH{ch[d]->revt();}rev=false;}return;} 18 }lct[maxn+maxm],*nodecnt; 19 int parent(node*x,node*&y){return (y=x->fa)?y->ch[0]==x?0:y->ch[1]==x?1:-1:-1;} 20 void rotate(node*x){ 21 node*y,*z;int d1=parent(x,y),d2=parent(y,z); 22 if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y; 23 y->fa=x;x->fa=z;x->ch[d1^1]=y; 24 if(d2!=-1) z->ch[d2]=x; 25 y->update();return; 26 } 27 void pushdown(node*x){ 28 static node*s[maxn];int top=0; 29 for(node*y;;x=y){ 30 s[top++]=x;y=x->fa; 31 if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break; 32 } while(top--) s[top]->down();return; 33 } 34 node*splay(node*x){ 35 pushdown(x);node*y,*z;int d1,d2; 36 while(true){ 37 if((d1=parent(x,y))<0) break; 38 if((d2=parent(y,z))<0){rotate(x);break;} 39 if(d1==d2) rotate(y),rotate(x); 40 else rotate(x),rotate(x); 41 } x->update();return x; 42 } 43 node*access(node*x){ 44 node*ret=NULL; 45 for(;x;x=x->fa) splay(x)->ch[1]=ret,(ret=x)->update(); 46 return ret; 47 } 48 void makeroot(int x){access(x+lct)->revt();return;} 49 void link(int x,int y){makeroot(x);splay(x+lct)->fa=lct+y;return;} 50 void cut(int x,int y){ 51 makeroot(x);node*p=(access(y+lct),splay(y+lct)); 52 p->ch[0]=p->ch[0]->fa=NULL;p->update();return; 53 } 54 node*findtop(int x){ 55 node*t=(access(x+lct),splay(x+lct));while(t->ch[0]) t->down(),t=t->ch[0];return t; 56 } 57 node*query(int x,int y){ 58 makeroot(x);return access(y+lct)->mx; 59 } 60 int n,m; 61 inline int read(){ 62 int x=0,sig=1;char ch=getchar(); 63 while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();} 64 while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar(); 65 return x*=sig; 66 } 67 inline void write(int x){ 68 if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x; 69 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 70 for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return; 71 } 72 int s[maxm],t[maxm]; 73 void init(){ 74 n=read();m=read();int ans=0,cnt=n;nodecnt=lct+n+1; 75 for(int i=1;i<=m;i++){ 76 s[i]=read();t[i]=read(); 77 node*q=nodecnt++;q->x=read();int k=q-lct;makeroot(k); 78 if(s[i]!=t[i]) { 79 if(findtop(s[i])!=findtop(t[i])){ 80 link(s[i],k);link(t[i],k);ans+=q->x;cnt--; 81 }else{ 82 node*p=query(s[i],t[i]);if(p->x>q->x) { 83 ans+=q->x-p->x;int id=p-lct-n; 84 cut(s[id],p-lct);cut(t[id],p-lct); 85 link(s[i],k);link(t[i],k);} 86 } 87 } 88 if(cnt==1) write(ans),ENT; 89 else puts("Not Yet"); 90 } 91 return; 92 } 93 void work(){ 94 return; 95 } 96 void print(){ 97 return; 98 } 99 int main(){init();work();print();return 0;}
时间: 2024-10-27 05:30:17