還不錯,就是理解題意的時候理解的久了一些。題目中的距離實際上是每兩個點在原樹上的距離,而新建的結點是不會影響的,所以總的距離和是原樹上任意兩點的距離之和;最短距離呢,實際上就是最短邊權了;最長距離,實際上就是新構成虛樹上樹的直徑了,當然得是有效點的。
所以,構建虛樹,然後再進行乙個樹形dp就可以了。
#include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define inf 0x3f3f3f3f3f3f3f3f
#define half (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define lson lsn, l, mid
#define rson rsn, mid+1, r
#define ql lson, ql, qr
#define qr rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxn = 1e6 + 7;
int n, q, qid[maxn << 1], log2[maxn];
struct build_graph
}edge[maxn << 1];
inline void addeddge(int u, int v, int w)
inline void _add(int u, int v, int w)
inline void init()
} old, now;
int dfn[maxn], tot, deep[maxn], fa[maxn][22];
inline bool cmp(int e1, int e2)
ll up_toroot[maxn] = ;
void pre_dfs(int u, int father)
}inline int lca(int u, int v)
if(u == v) return u;
for(int i=log2[n]; i>=0; i--)
}return fa[u][0];
}int stap[maxn << 1], stop;
inline void insert(int u)
int lca = lca(u, stap[stop]);
if(lca == stap[stop])
while(stop > 1 && dfn[lca] <= dfn[stap[stop - 1]])
if(lca ^ stap[stop])
stap[++stop] = u;
}bool used[maxn];
int k, siz[maxn];
ll down_min[maxn], down_max[maxn], ans_sum, ans_min, ans_max;
#define min_3(a, b, c) min(a, min(b, c))
#define max_3(a, b, c) max(a, max(b, c))
void dfs(int u)
if(used[u])
}void sum_dfs(int u)
now.head[u] = -1;
}inline void init()
log2[i] = k;
}}int main()
ans_sum = 0; ans_max = -inf; ans_min = inf;
dfs(stap[1]);
sum_dfs(stap[1]);
printf("%lld %lld %lld\n", ans_sum, ans_min, ans_max);
for(int i=1; i<=k; i++) used[qid[i]] = false;
}return 0;
}
P4103 HEOI2014 大工程 虛樹
虛樹板題一道。個人覺得這題比 消耗戰 更適合練板子 樹形dp更為簡單 說正解。注意到 p 2e 6 sum p le2e6 p 2 e6,這提示我們建一顆虛樹。建好後,2和3問就是求乙個樹上最短路,最長路,不再贅述。簡單說一下1,我們對於每一條邊統計有多少點對經過它。具體的,樹形dp的時候算出,即為...
P4103 HEOI2014 大工程 (虛樹)
觀察資料範圍是跟k有關的,因此我們考慮建立虛樹,對於維護三個值 總和就是常規的按每條路左右兩邊點數算貢獻,注意是特殊點的數量 之後我們維護mi i mx i 表示對於當前點,子樹中離他最近的特殊點在哪 includeusing namespace std typedef long long ll t...
P4103 HEOI2014 大工程 虛樹
戳這裡 虛樹板子題 首先有乙個 o qn 的暴力,就是對於每一次詢問,o n 的樹上 dp 我們統計一下每乙個點,它的子樹內離它最近 遠的關鍵點的距離,已經關鍵點的個數 對於第乙個詢問等價於 sum dep x dep y sum2 times dep lca 我們 dp 的時候順便統計一下每乙個點...