CF 196 Div2 D&&HDU 4679 && HDU 2196

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 }
HDU2196
  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 }
CF 196 div2 D
  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 }
HDU4679
原文地址:https://www.cnblogs.com/UnkelTao/p/3269051.html