求最小差值生成樹
考慮先把邊從小到大排序(從大到小也可以,就是反過來而已)
然後一條條邊列舉,如果兩端點還未聯通,直接聯通
如果整個圖已經聯通了,此時可以理解為列舉了邊的最大值(因為邊權從小到大排序了),最大值確定,就應該要讓最小值越大越好,又因為要在這兩個端點行成的路徑上刪掉乙個點,那麼就刪掉環上權值最小的點
所以按照上面的描述每次如果每聯通就聯通,如果聯通了就刪路徑權值最小邊並加新邊就行了,用 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...