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;
}
View Code

 

posted @ 2015-07-02 14:27  wzj_is_a_juruo  阅读(193)  评论(0编辑  收藏  举报