说是树形DP,其实就是求树的最长链嘛……

  K=1的时候明显是将树的最长链的两端连起来最优。

  但是K=2的时候怎么搞?

  考虑第一次找完树的最长链以后的影响:第一次找过的边如果第二次再走,对答案的贡献会变成-1,因为两次都选这一段的话,反而会使得这一段不得不走两次(如果只被选一次的话就可以只走一次),所以就将第一次找出的树的最长链上的边权值都改为-1。这个操作可以用链表实现(类比一下最小费用最大流的spfa实现!)

  题解:http://blog.csdn.net/qpswwww/article/details/43935861

 1 /**************************************************************
 2     Problem: 1912
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:580 ms
 7     Memory:5752 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1912
11 #include<vector>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 #define pb push_back
21 #define CC(a,b) memset(a,b,sizeof(a))
22 using namespace std;
23 inline int getint(){
24     int v=0,sign=1; char ch=getchar();
25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
27     return v*sign;
28 }
29 const int N=1e5+10,INF=~0u>>2;
30 typedef long long LL;
31 /******************tamplate*********************/
32 int head[N],to[N<<1],next[N<<1],len[N<<1],cnt=1;
33 void add(int x,int y){
34     to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=1;
35     to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt; len[cnt]=1;
36 }
37 int n,K;
38 int D,S,son1[N],son2[N];
39 int dfs(int x,int fa){
40     int m1=0,m2=0;
41     for(int i=head[x];i;i=next[i])
42         if (to[i]!=fa){
43             int nowh=dfs(to[i],x)+len[i];
44             if (nowh>m1){m2=m1;m1=nowh;son2[x]=son1[x];son1[x]=i;}
45             else if (nowh>m2){m2=nowh; son2[x]=i;}
46         }
47     if (D<m1+m2) D=m1+m2,S=x;
48     return m1;
49 }
50 int main(){
51 #ifndef ONLINE_JUDGE
52     freopen("1912.in","r",stdin);
53     freopen("1912.out","w",stdout);
54 #endif
55     n=getint(); K=getint();
56     F(i,2,n){
57         int x=getint(),y=getint();
58         add(x,y);
59     }
60     int ans=(n-1)<<1;
61     D=0;
62     CC(son1,-1);
63     CC(son2,-1);
64     dfs(1,-1);
65     ans-=D-1;
66     if (K>1){
67         D=0;
68         for(int i=son1[S];i!=-1;i=son1[to[i]]) len[i]=len[i^1]=-1;
69         for(int i=son2[S];i!=-1;i=son1[to[i]]) len[i]=len[i^1]=-1;
70         CC(son1,-1);
71         CC(son2,-1);
72         dfs(1,-1);
73         ans-=D-1;
74     }
75     printf("%d\n",ans);
76     return 0;
77 }
78 
View Code

相关文章:

  • 2021-07-07
  • 2021-07-21
  • 2021-10-27
  • 2021-05-19
  • 2022-12-23
  • 2021-07-15
  • 2021-06-16
  • 2021-07-06
猜你喜欢
  • 2022-12-23
  • 2021-08-15
  • 2021-09-12
  • 2021-08-10
  • 2021-05-22
  • 2021-06-06
  • 2022-01-19
相关资源
相似解决方案