題意:
給出乙個n個點m條邊的森林,q次詢問,第一種詢問要求輸出乙個點所在樹的直徑,第二種詢問要求合併兩個點所在的樹。
思路:先將初始的森林中各個樹的直徑求出來,然後用並查集維護。兩樹合併時,設直徑分別為len1,len2,新樹直徑為max(len1,len2,(len1/2)+(len2/2)+(len1%2)+(len2%2)+1),即兩顆舊樹的直徑,兩顆舊樹直徑的一半向上取整加一,中的較大值。
優化上可以用並查集路徑壓縮+啟發式合併,輸入掛。
**:
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define pb push_back
#define x first
#define y second
#define all(x) x.begin(),x.end()
#define ins(x) inserter(x,x.begin())
#define pii pair#define qclear(a) while(!a.empty())a.pop();
#define lowbit(x) (x&-x)
//#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define mst(a,b) memset(a,b,sizeof(a))
#define cout3(x,y,z) coutinline void out(int x)
int n,m,q;
vectormaps[maxn];
int fa[maxn];
int rk[maxn];
inline void init()
}inline int findfa(int x)
inline void meg(int a,int b)
for(int i=0;i>1)+(len2>>1)+(len1&1)+(len2&1)+1;
meg(u,v);
lens[findfa(u)]=max(len1,max(len2,len3));}}
return ;
}int main()
codeforces1141D題解 暴力 貪心
給出兩個長度為 n 1 n 150000 的僅含有小寫字母和 的字串,詢問兩個字串最多能有幾對匹配的字元。每個字母都可以與和它相同的字元匹配,可以與任意字元匹配,匹配與位置無關 輸出最大匹配對數,以及每一對中兩個字元在字串中的位置 cf1141d created by hao on 2019 4 1...
455 分發餅乾(C語言)
假設你是一位很棒的家長,想要給你的孩子們一些小餅乾。但是,每個孩子最多只能給一塊餅乾。對每個孩子 i 都有乙個胃口值 gi 這是能讓孩子們滿足胃口的餅乾的最小尺寸 並且每塊餅乾 j 都有乙個尺寸 sj 如果 sj gi 我們可以將這個餅乾 j 分配給孩子 i 這個孩子會得到滿足。你的目標是盡可能滿足...
Codeforces 587C 樹上倍增
題意 求樹上兩點路徑中的前 a 10 小的點權值。思路 類似lca倍增演算法來儲存 i 2 j 路上的 前 10 小個 的點權值。然後要寫乙個權值合併 具體求 u v 的話,就是先分別計算 和 減1是lca會重疊 然後再合併,輸出答案。include include include include ...