COJ979 WZJ的数据结构(负二十一)
试题描述
|
请你实现一个数据结构,完成这样的功能: 给你一个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 |
水水哒LCT,注意不要被坑
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define lc ch[x][0] #define rc ch[x][1] #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=700010; int ch[maxn][2],val[maxn],fa[maxn],pre[maxn],mx[maxn],flip[maxn]; void maintain(int x) { mx[x]=x; if(val[mx[lc]]>val[mx[x]]) mx[x]=mx[lc]; if(val[mx[rc]]>val[mx[x]]) mx[x]=mx[rc]; } void pushdown(int x) { if(!flip[x]) return; flip[x]=0;flip[lc]^=1;flip[rc]^=1; swap(lc,rc); } void rotate(int x) { int y=pre[x],z=pre[y],d=ch[y][0]==x; ch[y][d^1]=ch[x][d];pre[ch[x][d]]=y; ch[z][ch[z][1]==y]=x;pre[x]=z; ch[x][d]=y;pre[y]=x;maintain(y); } int S[maxn],top; void splay(int x) { for(int i=x;i;i=pre[i]) S[++top]=i; if(S[top]!=x) fa[x]=fa[S[top]]; while(top) pushdown(S[top--]); while(pre[x]) rotate(x); maintain(x); } void access(int x) { for(int y=0;x;x=fa[x]) { splay(x);pre[ch[x][1]]=0;fa[ch[x][1]]=x; ch[x][1]=y;pre[y]=x;maintain(y=x); } } void makeroot(int x) {access(x);splay(x);flip[x]^=1;} void link(int x,int y) {makeroot(x);fa[x]=y;} void cut(int x,int y) { makeroot(x);access(y);splay(y); pre[ch[y][0]]=ch[y][0]=0;maintain(y); } int query(int x,int y) {makeroot(x);access(y);splay(y);return mx[y];} int find(int x) {access(x);splay(x);while(ch[x][0]) x=ch[x][0];return x;} int u[maxn],v[maxn]; int main() { int n=read(),m=read(),ans=0,cnt=n,ret=0; rep(1,m) { u[i]=read();v[i]=read();val[n+i]=read(); if(u[i]==v[i]) { if(cnt==1) printf("%d\n",ans); else puts("Not Yet"); continue; } if(find(u[i])!=find(v[i])) cnt--,ans+=val[n+i],link(u[i],n+i),link(v[i],n+i); else { int t=query(u[i],v[i]); if(val[t]>val[n+i]) { cut(t,u[t-n]);cut(t,v[t-n]); link(u[i],n+i);link(v[i],n+i); ans-=val[t]-val[n+i]; } } if(cnt==1) printf("%d\n",ans); else puts("Not Yet"); } return 0; }