bzoj 1912 [Apio2010]patrol 巡逻 树形dp
2016-12-01 08:08
441 查看
如果K=1那么就加连接直径两段的边。
否则把直径上的边权赋为-1,然后再求一遍直径。
答案是(n-1)*2-(两次求出的直径和)+K
否则把直径上的边权赋为-1,然后再求一遍直径。
答案是(n-1)*2-(两次求出的直径和)+K
#include <bits/stdc++.h> using namespace std; #define N 110000 int n,K,tot; int f ,head ,nex[N<<1],to[N<<1]; int bj ,deep ,fa ,pos ; int p1,p2,ans,fin; void add(int x,int y) { tot++; nex[tot]=head[x];head[x]=tot; to[tot]=y; } void dfs(int x,int y) { deep[x]=deep[y]+1; f[x]=0;pos[x]=x;fa[x]=y; for(int i=head[x];i;i=nex[i]) if(to[i]!=y) { dfs(to[i],x); if(f[x]+f[to[i]]+bj[to[i]]>ans) { ans=f[x]+f[to[i]]+bj[to[i]]; p1=pos[x];p2=pos[to[i]]; } if(f[to[i]]+bj[to[i]]>f[x]) { f[x]=f[to[i]]+bj[to[i]]; pos[x]=pos[to[i]]; } } } int main() { //freopen("tt.in","r",stdin); scanf("%d%d",&n,&K); for(int i=1,x,y;i<n;i++) { scanf("%d%d",&x,&y); add(x,y);add(y,x); } for(int i=1;i<=n;i++)bj[i]=1; dfs(1,0);fin+=ans; if(K==2) { if(deep[p1]<deep[p2])swap(p1,p2); while(deep[p1]>deep[p2]) bj[p1]=-1,p1=fa[p1]; while(p1!=p2) { bj[p1]=-1;bj[p2]=-1; p1=fa[p1];p2=fa[p2]; } ans=-n; dfs(1,0);fin+=ans; } printf("%d\n",2*(n-1)-fin+K); return 0; }
相关文章推荐
- BZOJ 1912 [Apio2010]patrol 巡逻 - 树形DP(树的直径)
- 【bzoj1912】[Apio2010] patrol 巡逻 树形dp
- bzoj 1912: [Apio2010]patrol 巡逻【不是dp是枚举+堆】
- [bzoj1912][Apio2010]patrol 巡逻(树上dp)
- bzoj1912 [Apio2010]patrol 巡逻(dp求树上最长链)
- [BZOJ 1912][APIO 2010]patrol 巡逻(树的直径)
- BZOJ1912 [Apio2010]patrol 巡逻
- 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)
- BZOJ1912[Apio2010]patrol 巡逻
- [BZOJ 1912][Apio2010]patrol 巡逻:树的直径
- [BZOJ1912][Apio2010]patrol 巡逻(dfs+并查集+树形dp)
- 【bzoj1912】 APIO2010patrol巡逻 树的直径
- 【bzoj1912】[Apio2010]patrol 巡逻(树上最长链)
- 【bzoj1912】 Apio2010—patrol 巡逻
- bzoj 1912: [Apio2010]patrol 巡逻
- bzoj 1912 : [Apio2010]patrol 巡逻 树的直径
- 【BZOJ】【1912】【APIO2010】patrol巡逻
- bzoj1912 [Apio2010]patrol 巡逻
- bzoj1912 [Apio2010]patrol 巡逻(树的直径[变式])
- BZOJ1912[Apio2010]patrol 巡逻