2599: [IOI2011]Race
2018-06-02 18:04
232 查看
2599: [IOI2011]Race
分析
被memset卡。。。
点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少。然后先遍历子树,更新答案,然后在遍历一边更新T,防止出现两个起点在同一棵子树中的情况。
代码
#include<cstdio> #include<algorithm> #include<cctype> using namespace std; const int N = 200100; const int INF = 1e9; struct Edge{ int to,nxt,w; Edge() {} Edge(int a,int b,int c) {to = a,w = b,nxt = c;} }e[N<<1]; int head ,siz ,T[1000010]; bool vis ; int n,k,tot,Size,Num,Root,Ans = N; inline int read() { int x = 0,f = 1;char ch=getchar(); for (; !isdigit(ch); ch=getchar()) if(ch=='-')f=-1; for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0'; return x*f; } void add_edge(int u,int v,int w) { e[++tot] = Edge(v,w,head[u]);head[u] = tot; e[++tot] = Edge(u,w,head[v]);head[v] = tot; } void getRoot(int u,int fa) { siz[u] = 1; int mx = 0; for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (v == fa || vis[v]) continue; getRoot(v,u); siz[u] += siz[v]; mx = max(siz[v],mx); } mx = max(Size-siz[u],mx); if (mx < Num) Root = u,Num = mx; } void dfs1(int u,int fa,int L,int C) { if (L > k) return ; Ans = min(Ans,T[k-L]+C); for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (v == fa || vis[v]) continue; dfs1(v,u,L+e[i].w,C+1); } } void dfs2(int u,int fa,int L,int C,int f) { if (L > k) return ; if (f) T[L] = min(T[L],C); else T[L] = INF; for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (v == fa || vis[v]) continue; dfs2(v,u,L+e[i].w,C+1,f); } } void calcc(int u) { T[0] = 0; for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (vis[v]) continue; dfs1(v,u,e[i].w,1); dfs2(v,u,e[i].w,1,1); } for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (vis[v]) continue; dfs2(v,u,e[i].w,1,0); } } void solve(int u) { vis[u] = true; calcc(u); for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (vis[v]) continue; Size = siz[v],Root = 0,Num = 1e9; getRoot(v,0); solve(Root); } } int main() { n = read(),k = read(); for (int i=1; i<=k; ++i) T[i] = INF; for (int u,v,w,i=1; i<n; ++i) { u = read(),v = read(),w = read(); add_edge(u+1,v+1,w); if (w == k) {printf("-1");return 0;} } Size = n;Num = 1e9; getRoot(1,0); solve(Root); if (Ans == N) puts("-1"); else printf("%d",Ans); return 0; }
相关文章推荐
- bzoj 2599 [IOI2011]Race
- 2599: [IOI2011]Race
- bzoj2599 [IOI2011]Race
- bzoj2599: [IOI2011]Race
- Bzoj2599 [IOI2011]Race
- 【bzoj2599】[IOI2011]Race 树的点分治
- BZOJ2599 - [IOI2011]Race
- 【bzoj2599】: [IOI2011]Race
- 【BZOJ 2599】【IOI 2011】Race 点分治
- BZOJ2599: [IOI2011]Race 点分治
- bzoj2599: [IOI2011]Race
- 【BZOJ2599】[IOI2011]Race 树的点分治
- 【BZOJ】2599 [IOI2011]Race 点分治
- 【BZOJ 2599】 [IOI2011]Race 树的点分治
- [BZOJ2599][IOI2011]Race 点分治
- [BZOJ2599][IOI2011]Race-树上启发式合并(dsu on tree)
- BZOJ2599: [IOI2011]Race
- BZOJ2599 [IOI2011]Race
- [树的点分治] [树形DP] [BZOJ2599] [IOI2011] Race
- 2599: [IOI2011]Race