[BZOJ1912][Apio2010]patrol 巡逻(dfs+并查集+树形dp)
来源:互联网 发布:数据恢复软件哪个好 编辑:程序博客网 时间:2024/05/18 22:45
题目描述
传送门
题解
k=1时,首先使所有的路权都为1,求树上最长链,答案为2×(n-1)-(len1-1)
k=2时,在k=1的基础上,将第一次选取的链上的边权都赋为-1,然后再求树的直径记为len2,答案为2×(n-1)-(len1-1)-(len2-1)
注意第二次求树的直径有负边权dfs就不管用了,用树形dp
代码
#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int max_n=1e5+5;const int max_m=max_n;const int max_e=max_m*2;const int INF=2e9;int n,k,maxn,root,oldroot,len1,len2;int tot,point[max_n],next[max_e],v[max_e],c[max_e];int father[max_n],h[max_n],f[max_n],F[max_n],G[max_n];struct hp{int x,y;}edge[max_m];inline void add(int x,int y){ ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x;}inline void addedge(int x,int y,int z){ ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x; c[tot]=z;}inline void dfs(int x,int fa,int dep){ father[x]=fa; h[x]=dep; if (h[x]>maxn){maxn=h[x];root=x;} for (int i=point[x];i;i=next[i]) if (v[i]!=fa) dfs(v[i],x,dep+1);}inline int find(int x){if (x==f[x]) return x; else return f[x]=find(f[x]);}inline void merge(int x,int y){int f1=find(x),f2=find(y); f[f1]=f2;}inline void treedp(int x,int fa){ for (int i=point[x];i;i=next[i]) if (v[i]!=fa){ treedp(v[i],x); if (F[v[i]]+c[i]>F[x]){ G[x]=F[x]; F[x]=F[v[i]]+c[i]; } else G[x]=max(G[x],F[v[i]]+c[i]); } len2=max(len2,F[x]+G[x]);}int main(){ scanf("%d%d",&n,&k); for (int i=1;i<n;++i){ scanf("%d%d",&edge[i].x,&edge[i].y); add(edge[i].x,edge[i].y); } maxn=0; dfs(1,0,0); oldroot=root; memset(h,0,sizeof(0)),maxn=0; dfs(root,0,0); if (k==1){ printf("%d\n",maxn+1+(n-1-maxn)*2); return 0; } len1=maxn; tot=0; memset(point,0,sizeof(point)); memset(next,0,sizeof(next)); memset(v,0,sizeof(v)); memset(c,0,sizeof(c)); for (int i=1;i<=n;++i) f[i]=i; while (root!=oldroot){ addedge(father[root],root,-1); merge(father[root],root); root=father[root]; } for (int i=1;i<n;++i) if (find(edge[i].x)!=find(edge[i].y)){ addedge(edge[i].x,edge[i].y,1); merge(edge[i].x,edge[i].y); } len2=-INF; treedp(1,0); printf("%d\n",2*(n-1)-len1+1-len2+1);}
0 0
- [BZOJ1912][Apio2010]patrol 巡逻(dfs+并查集+树形dp)
- 【bzoj1912】[Apio2010] patrol 巡逻 树形dp
- [bzoj1912][Apio2010]patrol 巡逻(树上dp)
- BZOJ1912[Apio2010]patrol 巡逻
- 【bzoj1912】[Apio2010]patrol 巡逻
- bzoj1912: [Apio2010]patrol 巡逻
- bzoj1912 [Apio2010]patrol 巡逻
- bzoj 1912 [Apio2010]patrol 巡逻 树形dp
- [BZOJ1912][Apio2010]patrol 巡逻(树上最长链)
- 【bzoj1912】[Apio2010]patrol 巡逻(树上最长链)
- bzoj1912 [Apio2010]patrol 巡逻(树的直径[变式])
- APIO2010 巡逻 树形DP
- 【BZOJ1912】【APIO2010】巡逻(树最长链)
- [Apio2010]patrol 巡逻
- 1912: [Apio2010]patrol 巡逻
- 1912: [Apio2010]patrol 巡逻
- 【BZOJ 1912】 [Apio2010]patrol 巡逻
- bzoj 1912: [Apio2010]patrol 巡逻
- AS使用技巧
- web.xml中Servlet 配置的四个节点
- Ubuntu16.04安装Atom
- (OK) dnf——install docker on Fedora23
- 带头结点单链表的建立
- [BZOJ1912][Apio2010]patrol 巡逻(dfs+并查集+树形dp)
- No.01 Xcode(7.x) 键盘
- 微信双开是定时炸弹?关于非越狱iOS上微信分身高危插件ImgNaix的分析
- <meta name="description" content=">作用讲解
- How HashMap works in java
- Html5自学过程笔记
- 通过jsp向mysql数据库里面加入用户名与密码的主要代码。。。。
- timeStamp2String
- 递归回溯之八皇后问题