[2019.3.7]BZOJ1415 [Noi2005]聪聪和可可

首先,我们记录\(mo_{i,j}\)表示在点\(i\)到点\(j\)的任意一条最短路上,并且和\(i\)相邻的标号最小的节点,也就是当聪聪在点\(i\),可可在点\(j\)时,聪聪下一步会走的节点。

显然可以对每一个点\(i\)跑最短路计算\(mo_i\)

使用堆优化的Dijkstra的话这部分的总时间复杂度是\(O(n^2\log n)\)

然后进行dfs,记\(dfs(x,y)\)表示聪聪在\(x\),可可在\(y\)时的期望步数。

那么:

\(x=y\),直接返回0;

\(mo_{x,y}=y\)\(mo_{mo_{x,y},y}=y\),即聪聪走两步以下就可以抓到可可,返回1;

否则,设\(mo_{mo_{x,y},y}=to\),与\(y\)相邻的节点数量为\(m\),分别是\(p_1,p_2,p_3,...,p_m\)

那么答案=\(\frac{\sum_{t=1}^m[dfs(to,p_i)+1]+dfs(to,y)}{m+1}\)

显然不会死循环,因为每一次递归聪聪和可可的距离至少减少1。

可是这样会TLE。

所以我们要记忆化搜索。

code:

#include<bits/stdc++.h>
using namespace std;
const int INF=1e9;
struct edge{
    int t,nxt;
}e[2010];
struct node{
    int id,v;
    bool operator>(const node&y)const{
        return v==y.v?id<y.id:v<y.v;
    }
    bool operator<(const node&y)const{
        return v==y.v?id>y.id:v>y.v;
    }
}t;
int n,m,u,v,a,b,p[1010],cnt,be[1010],mo[1010][1010],vis[1010],mn[1010];
double s[1010][1010];
priority_queue<node>q;
void add(int x,int y){
    e[++cnt].t=y,e[cnt].nxt=be[x],be[x]=cnt;
}
void Dijkstra(int x){
    for(int i=1;i<=n;++i)mn[i]=INF,vis[i]=0;
    mn[x]=0,mo[x][x]=0,q.push((node){x,0});
    while(!q.empty()){
        while(!q.empty()&&(t=q.top(),vis[t.id]))q.pop();
        if(q.empty())return;
        q.pop(),vis[t.id]=1;
        for(int i=be[t.id];i;i=e[i].nxt)mo[x][e[i].t]>mo[x][t.id]&&mn[e[i].t]==mn[t.id]+1?mo[x][e[i].t]=(t.id==x?e[i].t:mo[x][t.id]):0,mn[e[i].t]>t.v+1?mn[e[i].t]=t.v+1,mo[x][e[i].t]=(t.id==x?e[i].t:mo[x][t.id]),q.push((node){e[i].t,mn[e[i].t]}),0:0;
    }
}
double dfs(int x,int y){
    if(x==y)return 0;
    if(s[x][y])return s[x][y];
    if(mo[x][y]==y)return s[x][y]=1;
    int to=mo[mo[x][y]][y];
    if(to==y)return s[x][y]=1;
    double ans=0;
    for(int i=be[y];i;i=e[i].nxt)ans+=dfs(to,e[i].t)+1;
    ans+=dfs(to,y)+1;
    return s[x][y]=1.0*ans/p[y];
}
int main(){
    scanf("%d%d%d%d",&n,&m,&a,&b);
    for(int i=1;i<=m;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u),++p[u],++p[v];
    for(int i=1;i<=n;++i)++p[i],Dijkstra(i);
    printf("%.3lf",dfs(a,b));
    return 0;
}
posted @ 2019-03-17 18:21  xryjr233  阅读(106)  评论(0编辑  收藏  举报