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 聪聪和可可 记忆化搜索的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1415NOI2005聪聪和可可

BZOJ1415: [Noi2005]聪聪和可可

bzoj 1415: [Noi2005]聪聪和可可

BZOJ1415NOI2005聪聪和可可(动态规划,数学期望)

bzoj1415[NOI2005]聪聪和可可

BZOJ 1415 NOI2005 聪聪和可可