感觉是很经典的题
记忆化时因为不好直接通过E判断某个状态是否已经求过,所以再加一个vis打标记即可
/*E[S][u]表示从u出发当前状态是S的期望*/ #include<bits/stdc++.h> using namespace std; #define N 16 #define INF 0x3f3f3f3f int mp[N][N],n,m; double E[N][1<<N]; bool vis[N][1<<N]; bool dfs(int S,int root){//在状态S下,从root点出发 if(S==(1<<n)-1){E[root][S]=0;return 1;} if(vis[root][S])return E[root][S]>0;//这个点这个状态已经被访问过 vis[root][S]=1; E[root][S]=5; int cnt=0,step; for(int i=0;i<n;i++){ if(!(S&(1<<i)) && mp[root][i]!=INF && dfs(S|(1<<i),i)){//状态集合里没有i,有边,且该边符合条件 step=S|(1<<i); cnt++; E[root][S]+=mp[root][i]+E[i][step]; } } if(!cnt){E[root][S]=0;return 0;} E[root][S]/=cnt; return true; } int main(){ int T;cin>>T; for(int tt=1;tt<=T;tt++){ memset(mp,0x3f,sizeof mp); memset(vis,0,sizeof vis); int u,v,w; cin>>n>>m; for(int i=1;i<=m;i++){ cin>>u>>v>>w; mp[u][v]=mp[v][u]=w; } dfs(1,0); printf("Case %d: %.10lf\n",tt,E[0][1]); } }
原文地址:https://www.cnblogs.com/zsben991126/p/10847923.html
时间: 2024-10-12 21:39:26