AC代码

我判断这道题是一道树状dp问题
以上是树状dp问题的基本思路(说白了就是递归,dfs嘛,简单)
当然我这个做法和树上dp可能还是有点不同,但都是靠子树返回的值进行计算
注释应该足够清楚,主要思路就是通过下面的节点传递上来的可传播validS进行求解,然后用dfs2打了一下链状数据结构的补丁
AC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <cmath> #include <bitset> #include <iterator> #include <random>
using namespace std; typedef long long ll; const ll N = static_cast<ll>(2e5)+10; vector<ll> g[N]; ll n,ans,recAns; bitset<N> vis;
ll dfs(ll x) { ll res=0,forAns=0; for(int i=0;i<g[x].size();i++) { ll fx=g[x][i]; if(vis[fx]) continue; vis[fx]=true; ll acc=dfs(fx); if(g[x].size()==3) forAns+=res*acc; res+=acc; } if(g[x].size()==2) { ans+=res; return 1; } if(g[x].size()==3) { ans+=forAns; return res; } return 0; }
void dfs2(ll x) { for(int i=0;i<g[x].size();i++) { ll fx=g[x][i]; if(vis[fx]) continue; vis[fx]=true; if(g[fx].size()==2 && g[x].size()==2) recAns+=1; dfs2(fx); } }
int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n; for(int i=1;i<=n-1;i++) { ll u, v ; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } vis[1]=true; dfs(1); vis.reset(); vis[1]=true; dfs2(1); ans-=recAns; cout<<ans<<endl; }
|
心路历程(WA,TLE,MLE……)
没过样例,主要问题在这里
degree==2的点也会阻隔validS传播
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <cmath> #include <bitset> #include <iterator>
using namespace std; typedef long long ll; const ll N=static_cast<ll>(2e5)+10; vector<ll> g[N]; ll n,dp[N],ans; bitset<N> vis;
ll dfs(ll x) { ll res=0,forAns=0; for(int i=0;i<g[x].size();i++) { ll fx=g[x][i]; if(vis[fx]) continue; vis[fx]=true; ll acc=dfs(fx); if(g[x].size()==3) forAns+=res*acc; res+=acc; } if(g[x].size()==2) { ans+=res; return res+1; } if(g[x].size()==3) { ans+=forAns; return res; } return 0; }
int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n; for(int i=1;i<=n-1;i++) { ll u, v ; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } for(int i=1;i<=n;i++) { if(vis[i]) continue; vis[i]=true; dfs(i); } cout<<ans<<endl; }
|
这个代码样例过了,但是全错
主要问题在于输入链状数据,答案一定为0。但我这个程序有点小问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <cmath> #include <bitset> #include <iterator>
using namespace std; typedef long long ll; const ll N = static_cast<ll>(2e5)+10; vector<ll> g[N]; ll n,dp[N],ans; bitset<N> vis;
ll dfs(ll x) { ll res=0,forAns=0; for(int i=0;i<g[x].size();i++) { ll fx=g[x][i]; if(vis[fx]) continue; vis[fx]=true; ll acc=dfs(fx); if(g[x].size()==3) forAns+=res*acc; res+=acc; } if(g[x].size()==2) { ans+=res; return 1; } if(g[x].size()==3) { ans+=forAns; return res; } return 0; }
int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n; for(int i=1;i<=n-1;i++) { ll u, v ; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } for(int i=1;i<=n;i++) { if(vis[i]) continue; vis[i]=true; dfs(i); } cout<<ans<<endl; }
|