P4206 [NOI2005] Cong Cong and Cocoa Problem Solving

Topic link

Expect DP + memory search

The most difficult part is the preprocessing. The transfer equation after processing is obviously

Let p [i, j] p[i,j]p[i,j ] means Cong Cong is iniii point, cocoa atjjAt j o'clock, where will Congcong go next?
Usennn times bfs preprocessing is enough

f [ i , j ] f[i,j] f[i,j ] means Cong Cong is iniii point, cocoa atjjThe expected value
of theanswer at point j ,letdi d_idiRepresents point iiThe degree
of i Lete [i, j] e[i,j]e[i,j ] meansjjj andiii adjacent point

Then, the transfer equation is obviously: f [i, j] = 1 + {∑ k = 1 djf [p [p [i, j], j], e [j, k]]} + f [p [p [ i, j], j], j] dj + 1 f[i,j]=1+\frac{\{ \sum\limits_{k=1}^{d_j}f[p[p[i,j] ,j],e[j,k]]\}+f[p[p[i,j],j],j]}{d_j+1}f[i,j]=1+dj+1{ k=1djf[p[p[i,j],j],e[j,k]]}+f[p[p[i,j],j],j]
In particular:

  • f [ i , i ] = 0 f[i,i]=0 f[i,i]=0
  • If p [i, j] = jp[i,j]=jp[i,j]=j p [ p [ i , j ] , j ] = j p[p[i,j],j]=j p[p[i,j],j]=j,则 f [ i , j ] = 1 f[i,j]=1 f[i,j]=1

The correctness is obvious

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int Maxn=1010;
const int inf=0x3f3f3f3f;
int p[Maxn][Maxn],d[Maxn];
int g[Maxn][Maxn],dis[Maxn];
double f[Maxn][Maxn];
bool vis[Maxn];
bool flag[Maxn][Maxn];
vector <int> e[Maxn];
int n,m,s,t;
inline int read()
{
    
    
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
inline void add(int x,int y)
{
    
    e[x].push_back(y);}
void bfs(int s)
{
    
    
	queue <int> q;
	fill(dis+1,dis+1+n,inf);
	memset(vis,0,sizeof(vis));
	dis[s]=0,vis[s]=1,q.push(s);
	while(q.size())
	{
    
    
		int x=q.front();
		q.pop();
		for(int i=0;i<e[x].size();++i)
		{
    
    
			int y=e[x][i];
			if(dis[y]>dis[x]+1)
			{
    
    
				dis[y]=dis[x]+1;
				if(!vis[y])vis[y]=1,q.push(y);
			}
		}
	}
	for(int i=1;i<=n;++i)
	g[s][i]=dis[i];
}
double dfs(int i,int j)
{
    
    
	if(flag[i][j])return f[i][j];
	flag[i][j]=1.0;
	if(i==j)return f[i][j]=0.0;
	if(p[i][j]==j || p[p[i][j]][j]==j)
	return f[i][j]=1.0;
	for(int k=0;k<e[j].size();++k)
	{
    
    
		int x=e[j][k];
		f[i][j]+=dfs(p[p[i][j]][j],x);
	}
	f[i][j]+=dfs(p[p[i][j]][j],j);
	f[i][j]/=(1.0*(d[j]+1.0));
	f[i][j]+=1.0;
	return f[i][j];
}
int main()
{
    
    
	n=read(),m=read(),s=read(),t=read();
	for(int i=1;i<=m;++i)
	{
    
    
		int x=read(),y=read();
		add(x,y),add(y,x);
	}
	for(int i=1;i<=n;++i)
	sort(e[i].begin(),e[i].end());
	for(int i=1;i<=n;++i)
	bfs(i),d[i]=e[i].size();
	for(int i=1;i<=n;++i)
	for(int j=1;j<=n;++j)
	{
    
    
		int tmp=inf,pos;
		for(int k=0;k<e[i].size();++k)
		{
    
    
			int x=e[i][k];
			if(g[x][j]<tmp)
			tmp=g[x][j],pos=x;
		}
		p[i][j]=pos;
	}
	printf("%.3lf\n",dfs(s,t));
	return 0;
}

Guess you like

Origin blog.csdn.net/Brian_Pan_/article/details/110048772