NC24758. [USACO 2010 Dec G]Cow Calisthenics
描述
Consider this rather linear cowpath set (a tree with 7 vertices): 1---2---3---4---5---6---7 If FJ can block two paths, he might choose them to make a map like this: 1---2 | 3---4 | 5---6---7 where the longest pathlength is 2, which would be the answer in this case. He can do no better than this.
输入描述
* Line 1: Two space separated integers: V and S
* Lines 2..V: Two space separated integers: and
输出描述
* Line 1: A single integer that is the best maximum pathlength FJ can achieve with S blocks
示例1
输入:
7 2 6 7 3 4 6 5 1 2 3 2 4 5
输出:
2
C++14(g++5.4) 解法, 执行用时: 126ms, 内存消耗: 8940K, 提交时间: 2019-10-14 17:33:12
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int n,m,u,v,mid,cnt; int len[N],head[N],nxt[2*N],to[2*N],tot=0; void add(int u,int v) { nxt[++tot]=head[u]; head[u]=tot; to[tot]=v; nxt[++tot]=head[v]; head[v]=tot; to[tot]=u; } void dfs(int u,int fa) { int now=0; for(int i=head[u];i;i=nxt[i]) { int v =to[i]; if(v==fa)continue; dfs(v,u); if(now+len[v]>mid) { cnt++; now=min(now,len[v]); } else now=max(now,len[v]); } len[u]=now+1; } bool check() { cnt=0; dfs(1,0); return cnt<=m; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(u,v); } int ans,l=1,r=n; while(l<=r) { mid=l+r>>1; if(check()) ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); }
C++11(clang++ 3.9) 解法, 执行用时: 111ms, 内存消耗: 10724K, 提交时间: 2020-02-26 20:39:22
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int n,k,tot,dis[N]; int cnt,head[N],to[2*N],nxt[2*N]; void adds(int x,int y) { to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt; return; } void dfs(int u,int fa,int limit) { if(tot>k) return; int mas=0; for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(v==fa) continue; dfs(v,u,limit); if(mas+dis[v]>limit) tot++,mas=min(mas,dis[v]); else mas=max(mas,dis[v]); } dis[u]=mas+1; return; } bool check(int limit) { memset(dis,0,sizeof(dis)); tot=0,dfs(1,0,limit); return tot<=k; } int main() { int a,b; scanf("%d%d",&n,&k); for(int i=1;i<n;i++) scanf("%d%d",&a,&b),adds(a,b),adds(b,a); int l=0,r=N; while(l<r) { int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; } printf("%d\n",l); return 0; }