Vijos1675 NOI2005 聪聪和可可 记忆化搜索
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vijos1675 NOI2005 聪聪和可可 记忆化搜索相关的知识,希望对你有一定的参考价值。
简单题,结果因为理解错题意懵逼了好久……
moveTo[x][y]表示聪聪在节点x,可可在节点y时,聪聪下一步应到达哪一个节点
dp[x][y]表示聪聪在节点x,可可在节点y,且轮到可可行动时,所需时间的数学期望(可可第一次行动不计入其内)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 7 typedef std::vector<int> Vec; 8 typedef Vec::iterator It; 9 10 const int maxN=1001; 11 const double notVis=-1.0; 12 13 Vec adj[maxN]; 14 int N,E; 15 int C,K; 16 int moveTo[maxN][maxN]; 17 18 void init() 19 { 20 for(int i=1;i<maxN;i++) adj[i].clear(); 21 memset(moveTo,0,sizeof(moveTo)); 22 } 23 24 bool input() 25 { 26 if(scanf("%d%d",&N,&E)==EOF) return false; 27 init(); 28 scanf("%d%d",&C,&K); 29 int v1,v2; 30 for(int i=1;i<=E;i++) 31 { 32 scanf("%d%d",&v1,&v2); 33 adj[v1].push_back(v2); 34 adj[v2].push_back(v1); 35 } 36 return true; 37 } 38 39 struct Node 40 { 41 int idx; 42 int layer; 43 Node(int i,int l):idx(i),layer(l) {} 44 bool operator < (const Node& other) const 45 { 46 return this->layer > other.layer || 47 (this->layer == other.layer && this->idx > other.idx); 48 } 49 }; 50 51 void calcMoveTo() 52 { 53 std::priority_queue<Node> pq; 54 for(int t=1;t<=N;t++) 55 { 56 moveTo[t][t]=t; 57 pq.push(Node(t,0)); 58 while(!pq.empty()) 59 { 60 Node cur=pq.top(); 61 pq.pop(); 62 int& v=cur.idx; 63 for(It x=adj[v].begin();x!=adj[v].end();++x) 64 if(!moveTo[*x][t]) 65 { 66 moveTo[*x][t]=v; 67 pq.push(Node(*x,cur.layer+1)); 68 } 69 } 70 } 71 } 72 73 double dp[maxN][maxN]; 74 75 double solve_aux(int Cpos,int Kpos) 76 { 77 if(dp[Cpos][Kpos]!=0.0) 78 return dp[Cpos][Kpos]; 79 for(It x=adj[Kpos].begin();x!=adj[Kpos].end();++x) 80 { 81 if(Cpos==(*x)) continue; 82 int Cnext=Cpos; bool ok=false; 83 for(int i=1;i<=2 && !ok;i++) 84 { 85 Cnext=moveTo[Cnext][*x]; 86 if(Cnext==(*x)) 87 { 88 dp[Cpos][Kpos]+=1.0; 89 ok=true; 90 } 91 } 92 if(!ok) dp[Cpos][Kpos]+=(1.0+solve_aux(Cnext,*x)); 93 } 94 dp[Cpos][Kpos]/=double(adj[Kpos].size()); 95 return dp[Cpos][Kpos]; 96 } 97 98 double solve() 99 { 100 if(C==K) return 0.0; 101 for(int i=1;i<=2;i++) 102 { 103 C=moveTo[C][K]; 104 if(C==K) return 1.0; 105 } 106 memset(dp,0,sizeof(dp)); 107 for(int i=1;i<=N;i++) adj[i].push_back(i); 108 return 1.0+solve_aux(C,K); 109 } 110 111 int main() 112 { 113 while(input()) 114 { 115 calcMoveTo(); 116 printf("%.3lf\n",solve()); 117 } 118 return 0; 119 }
以上是关于Vijos1675 NOI2005 聪聪和可可 记忆化搜索的主要内容,如果未能解决你的问题,请参考以下文章