• 最小差值生成树


    XVIII.最小差值生成树

    这题\(m^2\)暴力求最小生成树应该是过不去的……估计只有LCT能过去了。

    然后就是同IV.[NOI2014]魔法森林一致的方法,排序之后暴力断边连边即可。

    注意会有自环!!!虽然我也不知道为什么没判自环算我MLE……

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,res=0x3f3f3f3f;
    struct EDGE{
    	int u,v,w;
    	friend bool operator <(const EDGE &x,const EDGE &y){
    		return x.w<y.w;
    	}
    }e[200100];
    multiset<int>s;
    #define lson t[x].ch[0]
    #define rson t[x].ch[1]
    struct LCT{
    	int fa,ch[2],mn,val;
    	bool rev;
    }t[300100];
    inline int identify(int x){
    	if(x==t[t[x].fa].ch[0])return 0;
    	if(x==t[t[x].fa].ch[1])return 1;
    	return -1;
    }
    inline void pushup(int x){
    	t[x].mn=x;
    	if(lson&&t[t[x].mn].val>t[t[lson].mn].val)t[x].mn=t[lson].mn;
    	if(rson&&t[t[x].mn].val>t[t[rson].mn].val)t[x].mn=t[rson].mn;
    }
    inline void REV(int x){t[x].rev^=1,swap(lson,rson);}
    inline void pushdown(int x){
    	if(!t[x].rev)return;
    	if(lson)REV(lson);
    	if(rson)REV(rson);
    	t[x].rev=0;
    }
    inline void rotate(int x){
    	register int y=t[x].fa,z=t[y].fa,dirx=identify(x),diry=identify(y),b=t[x].ch[!dirx];
    	if(diry!=-1)t[z].ch[diry]=x;t[x].fa=z;
    	if(b)t[b].fa=y;t[y].ch[dirx]=b;
    	t[y].fa=x,t[x].ch[!dirx]=y;
    	pushup(y),pushup(x);
    }
    inline void pushall(int x){if(identify(x)!=-1)pushall(t[x].fa);pushdown(x);}
    inline void splay(int x){for(pushall(x);identify(x)!=-1;rotate(x))if(identify(t[x].fa)!=-1)rotate(identify(x)==identify(t[x].fa)?t[x].fa:x);}
    inline void access(int x){for(register int y=0;x;x=t[y=x].fa)splay(x),rson=y,pushup(x);}
    inline void makeroot(int x){access(x),splay(x),REV(x);}
    inline int findroot(int x){access(x),splay(x),pushdown(x);while(lson)x=lson,pushdown(x);splay(x);return x;}
    inline void split(int x,int y){makeroot(x),access(y),splay(y);}
    inline void link(int x,int y){makeroot(x),t[x].fa=y;}
    inline void cut(int x,int y){split(x,y),t[y].ch[0]=t[x].fa=0,pushup(y);}
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)t[i].val=0x3f3f3f3f;
    	for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    	sort(e+1,e+m+1);
    	for(int i=1;i<=m;i++){
    		t[i+n].val=e[i].w;
    		if(findroot(e[i].u)!=findroot(e[i].v))s.insert(e[i].w),link(e[i].u,i+n),link(e[i].v,i+n);
    		else{
    			if(e[i].u==e[i].v)continue;
    			split(e[i].u,e[i].v);
    			int tmp=t[e[i].v].mn;
    			cut(e[tmp-n].u,tmp),cut(e[tmp-n].v,tmp),s.erase(s.find(t[tmp].val)),s.insert(e[i].w),link(e[i].u,i+n),link(e[i].v,i+n);
    		}
    		if(s.size()==n-1)res=min(res,e[i].w-*s.begin());
    	}
    	printf("%d\n",res);
    	return 0;
    }
    

  • 相关阅读:
    设计模式7—装饰者模式【结构型】
    设计模式6—命令模式【行为型】
    vue工程类型—vue 多模块、vue多项目集成工程
    设计模式5—迭代器模式【行为型】
    设计模式4—代理模式【结构型】
    设计模式3—策略模式【行为型】
    用户权限管理系统(后台权限管理)
    https原理 及 证书
    设计模式2—单例模式【创建型】
    设计模式1—发布订阅者模式【行为型】
  • 原文地址:https://www.cnblogs.com/Troverld/p/14602119.html
Copyright © 2020-2023  润新知