Atcoder Beginner Contest152F(DFS+状压DP)
二维状压写成一维状压,省略加上第i条边这一维
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 vector<pair<int,int> >v[57]; 5 long long dp[1<<20]; 6 int x[57]; 7 bool dfs(int now,int fa,int root,int pos){//当前结点,父节点,终结点,所在边编号 8 if(now==root) 9 return 1; 10 for(auto it:v[now]){ 11 if(it.first!=fa&&dfs(it.first,now,root,pos)){ 12 x[it.second]^=1<<pos; 13 return 1; 14 } 15 } 16 return 0; 17 } 18 int main(){ 19 ios::sync_with_stdio(false); 20 cin.tie(NULL); 21 cout.tie(NULL); 22 int n; 23 cin>>n; 24 for(int i=1;i<n;++i){ 25 int a,b; 26 cin>>a>>b; 27 v[a].emplace_back(b,i); 28 v[b].emplace_back(a,i); 29 } 30 int m; 31 cin>>m; 32 for(int i=0;i<m;++i){ 33 int a,b; 34 cin>>a>>b; 35 dfs(a,0,b,i);//遍历a和b中间的所有结点,即遍历两点之间所有边 36 } 37 dp[0]=1;//所有的边全白 38 for(int i=1;i<n;++i)//每次添加一条边 39 for(int j=(1<<m)-1;j>=0;--j)//状压DP,从后往前是为了避免重复加 40 dp[j|x[i]]+=dp[j];//dp【j状态|加入第i条边变黑能满足的状态x[i]】+=dp【第i条边加入之前的状态j】 41 cout<<dp[(1<<m)-1];//全状态 42 return 0; 43 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)