[bzoj1415]聪聪与可可

直接求出任意两点的距离后记忆化搜索,用f[i][j]表示聪聪在i,可可在j的期望步数,由于i和j的最短路单调递减,所以搜不到环

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1005
 4 vector<int>v[N];
 5 queue<int>q;
 6 int n,m,s,t,x,y,d[N][N];
 7 double f[N][N];
 8 void bfs(int x){
 9     q.push(x);
10     d[x][x]=1;
11     while (!q.empty()){
12         int k=q.front();
13         q.pop();
14         for(int i=0;i<v[k].size();i++)
15             if (!d[x][v[k][i]]){
16                 d[x][v[k][i]]=d[x][k]+1;
17                 q.push(v[k][i]);
18             }
19     }
20 }
21 double dfs(int s,int t){
22     if (s==t)return 0;
23     if (d[s][t]<=3)return 1;
24     if (f[s][t])return f[s][t];
25     double &ans=f[s][t];
26     for(int i=0;i<v[s].size();i++)
27         if (d[v[s][i]][t]==d[s][t]-1){
28             s=v[s][i];
29             break;
30         }
31     for(int i=0;i<v[s].size();i++)
32         if (d[v[s][i]][t]==d[s][t]-1){
33             s=v[s][i];
34             break;
35         }
36     ans=dfs(s,t);
37     for(int i=0;i<v[t].size();i++)ans+=dfs(s,v[t][i]);
38     ans=ans/(v[t].size()+1.0)+1;
39     return ans;
40 }
41 int main(){
42     scanf("%d%d%d%d",&n,&m,&s,&t);
43     for(int i=1;i<=m;i++){
44         scanf("%d%d",&x,&y);
45         v[x].push_back(y);
46         v[y].push_back(x);
47     }
48     for(int i=1;i<=n;i++)sort(v[i].begin(),v[i].end());
49     for(int i=1;i<=n;i++)bfs(i);
50     printf("%.3f",dfs(s,t));
51 }
View Code

 

posted @ 2019-10-24 06:38  PYWBKTDA  阅读(105)  评论(0编辑  收藏  举报