UOJ274 P6664 溫暖會指引我們前行

2022-02-27 08:22:52 字數 1703 閱讀 4840

根據題目的條件(溫度各不相同)和要求(溫度排序後字典序最小),容易推出,實際上每次詢問就是要求兩個端點之間最低溫度最高的,同時不存在環(就是在最低溫最高基礎上最短)的一條路徑

其實和 水管局長 那題比較像,有連邊操作,想到用 lct 維護,對於每個新加入的邊:

這樣做的正確性也就比較顯然,其實就是維護乙個最大生成樹

還需要乙個技巧來維護邊的資訊,就是為每乙個邊新建乙個虛擬節點,權值(在這裡是長度)為邊權。

然後連邊時就用這個虛擬節點和它兩個端點相連,端點(實際節點)的點權為 \(0\),就能正常維護資訊了。

這樣修改操作就把那條邊的虛擬節點伸展到 lct 的根,然後更新。

查詢先看是否聯通,如果聯通就把那條路徑 split 出來,查詢長度和。

為了方便找路徑中最低溫的邊是哪個,節點結構體中的min其實是最低溫邊的標號。

**,洛谷uoj都能過,而且似乎並不像網上部落格說的一樣需要刻意卡常

#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 100005

#define m 300005

int n,m;

int tem[m];

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

int u[m],v[m];

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

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

#define min(x,y) (tem[x]son[k]=tree;tree->fa=fa;}

inline void pushdown(tr *tree)

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()

}inline void creat(int i,int l)

int main()

link(pos[id],pos[u]),link(pos[id],pos[v]);

u[id-n]=u;v[id-n]=v;

} else if(c=='c')

else

} }return 0;

}

UOJ 274 溫暖會指引我們前行

傳送門 小r的宿舍樓中有 n nn 個地點和一些路,一條路連線了兩個地點,小r可以通過這條路從其中任意乙個地點到達另外乙個地點。但在剛開始,小r還不熟悉宿舍樓中的任何一條路,所以他會慢慢地發現這些路,他在發現一條路時還會知道這條路的溫度和長度。每條路的溫度都是互不相同的。小r需要在宿舍樓中活動,每次...