18.10.04模拟赛T1。
这道题好神啊%%%
先SPFA预处理出距离,求出如果cat在x,mouse在y,cat的下一步去处:go[x][y]。
之后利用这个信息一边dfs一边计算概率。
感觉这个dfs真的很暴力......
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 7 int n,m,ct,ms; 8 int hd[1005],nx[2005],to[2005],ec; 9 int deg[1005]; 10 11 void edge(int af,int at) 12 { 13 to[++ec]=at; 14 nx[ec]=hd[af]; 15 hd[af]=ec; 16 } 17 18 int dis[1005][1005],go[1005][1005]; 19 queue<int>qq; 20 int inq[1005]; 21 22 void spfa(int s) 23 { 24 int *nd=dis[s]; 25 nd[s]=0; 26 qq.push(s); 27 while(!qq.empty()) 28 { 29 int p=qq.front(); 30 qq.pop(); 31 inq[p]=0; 32 for(int i=hd[p];i;i=nx[i]) 33 { 34 if(nd[p]+1<nd[to[i]]) 35 { 36 nd[to[i]]=nd[p]+1; 37 if(!inq[to[i]]) 38 inq[to[i]]=1,qq.push(to[i]); 39 } 40 } 41 } 42 } 43 44 double f[1005][1005]; 45 int vis[1005][1005]; 46 47 double cal(int x,int y) 48 { 49 if(vis[x][y])return f[x][y]; 50 if(x==y)return 0.00; 51 int fir=go[x][y]; 52 int sec=go[fir][y]; 53 if(fir==y||sec==y)return 1.00; 54 f[x][y]=1; 55 for(int i=hd[y];i;i=nx[i]) 56 f[x][y]+=cal(sec,to[i])/(deg[y]+1); 57 f[x][y]+=cal(sec,y)/(deg[y]+1); 58 vis[x][y]=1; 59 return f[x][y]; 60 } 61 62 int main() 63 { 64 scanf("%d%d%d%d",&n,&m,&ct,&ms); 65 for(int i=1;i<=m;i++) 66 { 67 int ff,tt; 68 scanf("%d%d",&ff,&tt); 69 edge(ff,tt),edge(tt,ff); 70 deg[ff]++,deg[tt]++; 71 } 72 memset(dis,0x3f,sizeof(dis)); 73 memset(go,0x3f,sizeof(go)); 74 for(int i=1;i<=n;i++)spfa(i); 75 for(int i=1;i<=n;i++) 76 for(int j=hd[i];j;j=nx[j]) 77 for(int k=1;k<=n;k++) 78 if(dis[i][k]-1==dis[to[j]][k]) 79 go[i][k]=min(go[i][k],to[j]); 80 printf("%.3lf",cal(ct,ms)); 81 return 0; 82 }