URAL1389. Roadworks(dp)
算个简单的树形DP吧 不知道是不是数据太水 竟然一A了
就是对于当前节点有没有被选中就行选最优 有没有被选中的意思是有没有与它相连的边被选中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 using namespace std; 9 #define N 100010 10 vector<int>d[N]; 11 int dp[N][3],g; 12 struct node 13 { 14 int u,v; 15 }p[N]; 16 int dfs(int u,int v,int f) 17 { 18 if(dp[v][f]!=-1) 19 return dp[v][f]; 20 int i; 21 int s[2][2] = {0}; 22 int flag =0,x=-1; 23 for(i = 0 ; i < d[v].size() ; i++) 24 { 25 int tv = d[v][i]; 26 if(tv==u) continue; 27 flag = 1; 28 int s1 = dfs(v,tv,0); 29 if(f) 30 { 31 s[(i+1)%2][0] = s[i%2][0]+s1; 32 } 33 else 34 { 35 int s2 = dfs(v,tv,1)+1; 36 s[(i+1)%2][0] = s[i%2][0]+s1; 37 if(s[i%2][1]+s1<s[i%2][0]+s2) 38 { 39 s[(i+1)%2][1] = s[i%2][0]+s2; 40 x = tv; 41 } 42 else 43 s[(i+1)%2][1] = s[i%2][1]+s1; 44 } 45 } 46 if(!flag) 47 { 48 return dp[v][f] = 0; 49 } 50 if(x!=-1) 51 { 52 g++; 53 p[g].u = v; 54 p[g].v = x; 55 } 56 int maxz = 0; 57 for(i = 0 ; i < 2 ; i++) 58 maxz = max(maxz,max(s[0][i],s[1][i])); 59 return dp[v][f] = maxz; 60 } 61 int main() 62 { 63 int i,n,m; 64 while(cin>>n>>m) 65 { 66 memset(dp,-1,sizeof(dp)); 67 for(i = 0 ; i <= n ;i++) 68 d[i].clear(); 69 for(i = 1; i <= m ;i++) 70 { 71 int u,v; 72 cin>>u>>v; 73 d[u].push_back(v); 74 d[v].push_back(u); 75 } 76 dfs(-1,1,0); 77 cout<<dp[1][0]<<endl; 78 for(i = 1; i <= g ; i++) 79 cout<<p[i].u<<" "<<p[i].v<<endl; 80 } 81 return 0; 82 }