zoukankan      html  css  js  c++  java
  • 最小差值生成树

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

  • 相关阅读:
    LeetCode题解之Flipping an Image
    LeetCode 之Find Minimum in Rotated Sorted Array
    LeetCode题解Transpose Matrix
    LeetCode 题解之Minimum Index Sum of Two Lists
    LeetCode题解之Intersection of Two Linked Lists
    LeetCode 题解之Add Two Numbers II
    LeetCode题解之Add two numbers
    href="#"与href="javascript:void(0)"的区别
    有关ie9 以下不支持placeholder属性以及获得焦点placeholder的移除
    ie7下属性书写不规范造成的easyui 弹窗布局紊乱
  • 原文地址:https://www.cnblogs.com/Troverld/p/14602119.html
Copyright © 2011-2022 走看看