简单题,结果因为理解错题意懵逼了好久……
moveTo[x][y]表示聪聪在节点x,可可在节点y时,聪聪下一步应到达哪一个节点
dp[x][y]表示聪聪在节点x,可可在节点y,且轮到可可行动时,所需时间的数学期望(可可第一次行动不计入其内)
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> typedef std::vector<int> Vec; typedef Vec::iterator It; ; const double notVis=-1.0; Vec adj[maxN]; int N,E; int C,K; int moveTo[maxN][maxN]; void init() { ;i<maxN;i++) adj[i].clear(); memset(moveTo,,sizeof(moveTo)); } bool input() { if(scanf("%d%d",&N,&E)==EOF) return false; init(); scanf("%d%d",&C,&K); int v1,v2; ;i<=E;i++) { scanf("%d%d",&v1,&v2); adj[v1].push_back(v2); adj[v2].push_back(v1); } return true; } struct Node { int idx; int layer; Node(int i,int l):idx(i),layer(l) {} bool operator < (const Node& other) const { return this->layer > other.layer || (this->layer == other.layer && this->idx > other.idx); } }; void calcMoveTo() { std::priority_queue<Node> pq; ;t<=N;t++) { moveTo[t][t]=t; pq.push(Node(t,)); while(!pq.empty()) { Node cur=pq.top(); pq.pop(); int& v=cur.idx; for(It x=adj[v].begin();x!=adj[v].end();++x) if(!moveTo[*x][t]) { moveTo[*x][t]=v; pq.push(Node(*x,cur.layer+)); } } } } double dp[maxN][maxN]; double solve_aux(int Cpos,int Kpos) { if(dp[Cpos][Kpos]!=0.0) return dp[Cpos][Kpos]; for(It x=adj[Kpos].begin();x!=adj[Kpos].end();++x) { if(Cpos==(*x)) continue; int Cnext=Cpos; bool ok=false; ;i<= && !ok;i++) { Cnext=moveTo[Cnext][*x]; if(Cnext==(*x)) { dp[Cpos][Kpos]+=1.0; ok=true; } } if(!ok) dp[Cpos][Kpos]+=(1.0+solve_aux(Cnext,*x)); } dp[Cpos][Kpos]/=double(adj[Kpos].size()); return dp[Cpos][Kpos]; } double solve() { if(C==K) return 0.0; ;i<=;i++) { C=moveTo[C][K]; if(C==K) return 1.0; } memset(dp,,sizeof(dp)); ;i<=N;i++) adj[i].push_back(i); return 1.0+solve_aux(C,K); } int main() { while(input()) { calcMoveTo(); printf("%.3lf\n",solve()); } ; }