3道很相似的树形DP阿~~~~入门题目~~~悲催~~~记录下水题~~~
首先HDU2196~~~
求树上每个点到其最远点的距离~~~~~
做法比较挫~~2次BFS~~首先将无根树转换成有根树~~直接把1作为根就好~~~
假设dp[i][0]是向下最大值~~~dp[i][2]是向下次大值~~~dp[i][1]是向上的最大值~~~
最终的结果就是max(dp[i][0],dp[i][1]);
第一次BFS()求出根节点到子节点的最远距离和次远距离~~~dp[i][2]=max(dp[i][2],dp[j][0]+w[i]) 如果dp[i][2]>dp[i][0]则交换~~~
第二次BFS()则可以求出每个点的最远距离了~~~如果该节点的父亲节点的最远距离路过该节点~~~
如果dp[u][0]>dp[v][0]+w[i] //也就是最大值不经过该点~~~dp[v][1]=max(dp[v][1],dp[u][0]+w[i]);
否则dp[v][1]=max(dp[v][1],dp[u][2]+w[i]);
当然可能是从根的上面过来的~~dp[v][1]=max(dp[v][1],dp[u][1]+w[i]);
(第一次交的暴力枚举次大在HDU上也过了~~但是CF上TLE了~~~)
CF 196 D~~~~
意思差不多。。只是不是最远点。。是到固定的一些点的最远距离~~~~于是预处理下对于固定的点距离dp[i][0]=dp[i][1]=dp[i][2]=0~~其他的预处理成-inf这样最远的距离肯定在这些固定点中~~~然后解法完全一样~~~~
HDU 4679~~~
多校联合题目~~~此题求一条边分成两科子树的树的直径~~~ 似乎有求直径的算法~~木有想到。。做完前两个题想到了一个可行的解法~~~
2次BFS
第一次求出最大值,次小值,次次小值~~分别用dp[i][0],dp[i][1],dp[i][2]保存~~~
二次BFS的时候则可以利用3个值,计算出向上的最远距离~~以及直径~~~
直径就等于~~该节点的父亲向下的不包含该节点的最大的两个值的和~~或者父亲向上来的最大值加上根向下不包含该节点的最大值~~两个中大的一个~~~
包不包含则看该节点向下的最大值加上它到父亲的距离~~与父亲向下的最大值作比较~~~此外(手动开栈~~~~)
代码很挫~~可能有bug~~
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <climits> 6 #include <cctype> 7 #include <ctime> 8 9 #include <algorithm> 10 #include <iostream> 11 #include <queue> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <stack> 16 17 #define SQR(x) ((x)*(x)) 18 #define rep(i, n) for (int i=0; i<(n); ++i) 19 #define repd(i,n) for(int i=1;i<=(n);++i) 20 #define repf(i, a, b) for (int i=(a); i<=(b); ++i) 21 #define reps(i, a, b) for (int i=(a); i>=(b); --i) 22 #define PB push_back 23 #define MP(A, B) make_pair(A, B) 24 #define pow2(n) (1<<(n)) 25 #define pi acos(-1) 26 #define eps 0.00000001 27 #define lg(n) log10((n)*1.0) 28 #define MaxN 101000 29 #define mod 1000000007 30 #define mod2 1000000009 31 #define mod3 1000007 32 #define inf 0x1fffffff; 33 #define inf2 0x7fffffffffffffff 34 #define ll long long 35 #define typed int 36 using namespace std; 37 void data(){ 38 freopen("data.in","r",stdin); 39 freopen("data.out","w",stdout); 40 } 41 int pnt[MaxN],nxt[MaxN],head[MaxN]; 42 int dp[MaxN][3]; 43 int w[MaxN]; 44 int used[MaxN]; 45 int n,k,a,b; 46 int len; 47 void addeg(int u,int v,int k){ 48 pnt[len] = v; 49 w[len]= k; 50 nxt[len] = head[u]; 51 head[u] = len++; 52 } 53 54 void dfs(int u){ 55 // cout<<"0: "<<u<<" "<<dp[u][1]<<" "<<dp[u][0]<<endl; 56 int v; 57 used[u]=1; 58 for(int i=head[u];i!=-1;i=nxt[i]){ 59 v=pnt[i]; 60 if(!used[v]){ 61 used[v]=1; 62 dfs(v); 63 //cout<<u<<" "<<v<<endl; 64 dp[u][2]=max(dp[u][2],dp[v][0]+w[i]); 65 if(dp[u][0]<dp[u][2])swap(dp[u][0],dp[u][2]); 66 } 67 } 68 // cout<<u<<" "<<dp[u][0]<<endl; 69 } 70 void dfs2(int u){ 71 int v; 72 used[u]=1; 73 for(int i=head[u];i!=-1;i=nxt[i]){ 74 v=pnt[i]; 75 if(!used[v]){ 76 used[v]=1; 77 //cout<<u<<" "<<v<<endl; 78 if(dp[u][0]>dp[v][0]+w[i]){ 79 // cout<<"kkk"<<endl; 80 dp[v][1]=max(dp[v][1],max(dp[u][0]+w[i],dp[u][1]+w[i])); 81 } 82 else{ 83 // cout<<"kkkk2"<<endl; 84 dp[v][1]=max(dp[v][1],dp[u][2]+w[i]); 85 dp[v][1]=max(dp[v][1],dp[u][1]+w[i]); 86 } 87 // cout<<"u="<<u<<" v="<<v<<" "<<dp[u][0]<<" "<<dp[u][1]<<" "<<dp[v][1]<<endl; 88 dfs2(v); 89 } 90 } 91 } 92 void init(){ 93 len=0; 94 memset(head,-1,sizeof(head)); 95 memset(used,0,sizeof(used)); 96 } 97 int main(){ 98 //data(); 99 while(~scanf("%d",&n)){ 100 init(); 101 repf(i,2,n){ 102 scanf("%d%d",&a,&b); 103 addeg(a,i,b); 104 addeg(i,a,b); 105 } 106 repf(i,0,n){dp[i][0]=0;dp[i][1]=0;dp[i][2]=0;} 107 dfs(1); 108 memset(used,0,sizeof(used)); 109 dfs2(1); 110 repf(i,1,n) 111 printf("%d ",max(dp[i][0],dp[i][1])); 112 } 113 return 0; 114 }
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <climits> 6 #include <cctype> 7 #include <ctime> 8 9 #include <algorithm> 10 #include <iostream> 11 #include <queue> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <stack> 16 17 #define SQR(x) ((x)*(x)) 18 #define rep(i, n) for (int i=0; i<(n); ++i) 19 #define repd(i,n) for(int i=1;i<=(n);++i) 20 #define repf(i, a, b) for (int i=(a); i<=(b); ++i) 21 #define reps(i, a, b) for (int i=(a); i>=(b); --i) 22 #define PB push_back 23 #define MP(A, B) make_pair(A, B) 24 #define pow2(n) (1<<(n)) 25 #define pi acos(-1) 26 #define eps 0.00000001 27 #define lg(n) log10((n)*1.0) 28 #define MaxN 110000 29 #define mod 1000000007 30 #define mod2 1000000009 31 #define mod3 1000007 32 #define inf 2147483647 33 #define inf2 0x7fffffffffffffff 34 #define ll long long 35 #define typed int 36 using namespace std; 37 void data(){ 38 freopen("data.in","r",stdin); 39 freopen("data.out","w",stdout); 40 } 41 int pnt[MaxN],nxt[MaxN],head[MaxN]; 42 int dp[MaxN][3]; 43 int w[MaxN]; 44 int used[MaxN]; 45 int n,m,k,a,b; 46 int len; 47 void addeg(int u,int v){ 48 pnt[len] = v; 49 w[len]= 1; 50 nxt[len] = head[u]; 51 head[u] = len++; 52 } 53 void dfs(int u){ 54 // cout<<"0: "<<u<<" "<<dp[u][1]<<" "<<dp[u][0]<<endl; 55 int v; 56 used[u]=1; 57 for(int i=head[u];i!=-1;i=nxt[i]){ 58 v=pnt[i]; 59 if(!used[v]&&v!=0){ 60 used[v]=1; 61 dfs(v); 62 // cout<<"U="<<u<<" "<<v<<endl; 63 dp[u][2]=max(dp[u][2],dp[v][0]+w[i]); 64 if(dp[u][2]>dp[u][0])swap(dp[u][0],dp[u][2]); 65 } 66 } 67 // cout<<u<<" "<<dp[u][0]<<endl; 68 } 69 void dfs2(int u){ 70 int v; 71 used[u]=1; 72 for(int i=head[u];i!=-1;i=nxt[i]){ 73 v=pnt[i]; 74 if(!used[v]){ 75 used[v]=1; 76 //cout<<u<<" "<<v<<endl; 77 if(dp[u][0]>dp[v][0]+w[i]){ 78 // cout<<"kkk"<<endl; 79 dp[v][1]=max(dp[v][1],dp[u][0]+w[i]); 80 } 81 else{ 82 // cout<<"kkkk2"<<endl; 83 dp[v][1]=max(dp[v][1],dp[u][2]+w[i]); 84 } 85 dp[v][1]=max(dp[v][1],dp[u][1]+w[i]); 86 // cout<<"u="<<u<<" v="<<v<<" "<<dp[u][0]<<" "<<dp[u][1]<<" "<<dp[v][1]<<endl; 87 dfs2(v); 88 } 89 } 90 } 91 void init(){ 92 len=0; 93 memset(head,-1,sizeof(head)); 94 memset(used,0,sizeof(used)); 95 repf(i,0,n){dp[i][0]=-inf;dp[i][1]=-inf;dp[i][2]=-inf;} 96 } 97 98 int main(){ 99 //data(); 100 while(~scanf("%d%d%d",&n,&m,&k)){ 101 init(); 102 rep(i,m){scanf("%d",&a);dp[a][0]=0;dp[a][1]=0;} 103 repf(i,2,n){ 104 scanf("%d%d",&a,&b); 105 addeg(b,a); 106 used[a]=1; 107 } 108 int head=-1; 109 repd(i,n)if(!used[i]){head=i;break;} 110 111 if(head!=-1){ 112 memset(used,0,sizeof(used)); 113 dfs(head); 114 memset(used,0,sizeof(used)); 115 dfs2(head); 116 } 117 int cnt=0; 118 // repf(i,1,n){cout<<"i="<<i<<" "<<dp[i][0]<<" "<<dp[i][1]<<endl;} 119 repf(i,1,n) if(max(dp[i][0],dp[i][1])<=k)cnt++; 120 printf("%d ",cnt); 121 } 122 return 0; 123 }
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <climits> 6 #include <cctype> 7 #include <ctime> 8 #pragma comment(linker,"/STACK:102400000,102400000") 9 #include <algorithm> 10 #include <iostream> 11 #include <queue> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <stack> 16 17 #define SQR(x) ((x)*(x)) 18 #define rep(i, n) for (int i=0; i<(n); ++i) 19 #define repd(i,n) for(int i=1;i<=(n);++i) 20 #define repf(i, a, b) for (int i=(a); i<=(b); ++i) 21 #define reps(i, a, b) for (int i=(a); i>=(b); --i) 22 #define PB push_back 23 #define MP(A, B) make_pair(A, B) 24 #define pow2(n) (1<<(n)) 25 #define pi acos(-1) 26 #define eps 0.00000001 27 #define lg(n) log10((n)*1.0) 28 #define MaxN 400000 29 #define mod 1000000007 30 #define mod2 1000000009 31 #define mod3 1000007 32 #define inf 2147483647 33 #define inf2 0x7fffffffffffffff 34 #define ll long long 35 #define typed int 36 using namespace std; 37 void data(){ 38 freopen("data.in","r",stdin); 39 freopen("data.out","w",stdout); 40 } 41 int pnt[MaxN],nxt[MaxN],head[MaxN]; 42 int dp[MaxN][3]; 43 int G[MaxN],D[MaxN]; 44 int w[MaxN],val[MaxN]; 45 int used[MaxN]; 46 int n,m,k,a,b; 47 int len; 48 void addeg(int u,int v,int k){ 49 pnt[len] = v; 50 w[len]= 1; 51 val[len]= k; 52 nxt[len] = head[u]; 53 head[u] = len++; 54 } 55 void dfs(int u){ 56 // cout<<"0: "<<u<<" "<<dp[u][1]<<" "<<dp[u][0]<<endl; 57 int v; 58 used[u]=1; 59 for(int i=head[u];i!=-1;i=nxt[i]){ 60 v=pnt[i]; 61 if(!used[v]&&v!=0){ 62 used[v]=1; 63 dfs(v); 64 // cout<<"U="<<u<<" "<<v<<endl; 65 dp[u][2]=max(dp[u][2],dp[v][0]+w[i]); 66 if(dp[u][2]>dp[u][1])swap(dp[u][1],dp[u][2]); 67 if(dp[u][1]>dp[u][0])swap(dp[u][1],dp[u][0]); 68 } 69 } 70 // cout<<u<<" "<<dp[u][0]<<" "<<dp[u][1]<<" "<<dp[u][2]<<endl; 71 } 72 void dfs2(int u){ 73 int v; 74 used[u]=1; 75 for(int i=head[u];i!=-1;i=nxt[i]){ 76 v=pnt[i]; 77 if(!used[v]){ 78 used[v]=1; 79 // cout<<u<<" "<<v<<endl; 80 81 if(dp[u][0]>dp[v][0]+w[i]){ 82 // cout<<"kkk"<<endl; 83 G[v]=max(G[v],dp[u][0]+w[i]); 84 if(dp[u][1]>dp[v][0]+w[i]) 85 D[i]=max(D[i],dp[u][0]+dp[u][1]); 86 else 87 D[i]=max(D[i],dp[u][0]+dp[u][2]); 88 D[i]=max(D[i],G[u]+dp[u][0]); 89 } 90 else{ 91 // cout<<"kkkk2"<<endl; 92 G[v]=max(G[v],dp[u][1]+w[i]); 93 D[i]=max(D[i],dp[u][1]+dp[u][2]); 94 D[i]=max(D[i],G[u]+dp[u][1]); 95 } 96 G[v]=max(G[v],G[u]+w[i]); 97 D[i]=max(D[i],dp[v][0]+dp[v][1]); 98 99 dfs2(v); 100 } 101 } 102 } 103 void init(){ 104 len=0; 105 memset(head,-1,sizeof(head)); 106 memset(used,0,sizeof(used)); 107 memset(D,0,sizeof(D)); 108 memset(G,0,sizeof(G)); 109 repf(i,0,n){dp[i][0]=0;dp[i][1]=0;dp[i][2]=0;} 110 } 111 112 int main(){ 113 //data(); 114 int T,t=0; 115 cin>>T; 116 while(T--&&~scanf("%d",&n)){ 117 init(); 118 rep(i,n-1){ 119 scanf("%d%d%d",&a,&b,&k); 120 addeg(b,a,k); 121 addeg(a,b,k); 122 } 123 if(n==2){printf("Case #%d: 1 ",(++t));continue;} 124 memset(used,0,sizeof(used)); 125 dfs(1); 126 memset(used,0,sizeof(used)); 127 dfs2(1); 128 int ans=-1; 129 int maxx=inf; 130 rep(i,len){ 131 // cout<<"D["<<i<<"]="<<D[i]<<endl; 132 // cout<<"val["<<i<<"]="<<val[i]<<endl; 133 if(D[i]!=0){ 134 if(maxx>val[i]*D[i]){maxx=val[i]*D[i];ans=i/2+1;} 135 // else if(maxx==D[i]&&val[i]<val[ans]){ans=i/2+1;} 136 else{} 137 } 138 // cout<<maxx<<" "<<ans<<endl; 139 } 140 printf("Case #%d: %d ",(++t),ans); 141 } 142 return 0; 143 }