根據題目的條件(溫度各不相同)和要求(溫度排序後字典序最小),容易推出,實際上每次詢問就是要求兩個端點之間最低溫度最高的,同時不存在環(就是在最低溫最高基礎上最短)的一條路徑
其實和 水管局長 那題比較像,有連邊操作,想到用 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需要在宿舍樓中活動,每次...