P4234 最小差值生成樹

2022-02-27 08:22:51 字數 1729 閱讀 5750

求最小差值生成樹

考慮先把邊從小到大排序(從大到小也可以,就是反過來而已)

然後一條條邊列舉,如果兩端點還未聯通,直接聯通

如果整個圖已經聯通了,此時可以理解為列舉了邊的最大值(因為邊權從小到大排序了),最大值確定,就應該要讓最小值越大越好,又因為要在這兩個端點行成的路徑上刪掉乙個點,那麼就刪掉環上權值最小的點

所以按照上面的描述每次如果每聯通就聯通,如果聯通了就刪路徑權值最小邊並加新邊就行了,用 lct 維護,因為涉及邊的資訊,還要用新建虛擬節點表示邊

然後每次列舉時,如果整個圖聯通,就用當前邊權減去當前全域性最小值,全域性最小值用帶刪除的堆維護的,好像有點麻煩了

#include#include#include#include#include#include#include#define reg register

#define en std::puts("")

#define ll long long

inline int read()

while(c>='0'&&c<='9')

return y?x:-x;

}#define n 50005

#define m 200005

int n,m;

int u[m],v[m],w[m];

int tmp[10];

struct tr*null,*pos[n+m],dizhi[n+m];

#define ident(tree,fa) (fa->son[1]==tree)

#define notroot(tree) (tree->fa->son[0]==tree||tree->fa->son[1]==tree)

inline void connect(tr *tree,tr *fa,int k)

inline void pushdown(tr *tree)

inline int min(int x,int y)

inline void pushup(tr *tree)

inline void rotate(tr *tree)

inline void splay(reg tr *tree)

}inline void access(reg tr *x)

}inline void makeroot(tr *x)

inline tr *findroot(tr *x)

inline int linked(tr *x,tr *y)

inline void split(tr *x,tr *y)

inline void link(tr *x,tr *y)

inline void cut(tr *x,tr *y)

inline void init()

w[0]=1e9;w[m+1]=-1e9;

}inline void creat(int i)

struct edgesedge[m];

inline int cmp_edge(edges a,edges b)

inline void insert(int num)

inline int top()

}heap;

int main()

else

if(cnt==n) ans=std::min(ans,w[i]+heap.top());

} printf("%d",ans);

return 0;

}

P4234 最小差值生成樹

題目鏈結 題目描述 給定乙個點標號從 1 11 到 n nn 的 有 m mm 條邊的無向圖,求邊權最大值與最小值的差值最小的生成樹。圖可能存在自環。輸入格式 第一行有兩個整數,表示圖的點數 n nn 和邊數 mmm。接下來 m mm 行,每行三個整數 u,v w u,v,w u,v,w,表示存在一...

洛谷 p4234 最小差值生成樹

求最長邊與最短邊差值最小的生成樹.lct裸題.將邊按照邊權從小到大排序,產生生成樹的同時立即更新答案.如果加入一條邊的時候出現了環,把環上最小的邊去掉加入該邊.每次跑最小值即可,用lct可以較方便地維護.為什麼re了啊啊啊啊啊啊啊啊啊 include ithea myse valgulious na...

luoguP4234 最小差值生成樹

按照邊的權值從小到大排序,依次加入,並刪除能夠刪除的權值最小的一條邊,用 set 維護當前所有邊的邊權,並查集維護聯通性,lct 維護兩點間最小值和 link cut 操作即可 include define mp make pair using namespace std typedef unsig...