我們可以用n次bfs預處理出 to陣列,to[i][j]表示聰聰從i點到j點第一步會走哪個點。
那麼對於聰聰在i點,可可在j點,聰聰先走,定義dp[i][j]表示步數期望。
那麼顯然有dp[i][j]=(sigma(dp[p][w])+dp[p][j])/(dee[j]+1)+1.
其中p表示to[to[i][j]][j],w表示j點鄰接的點。
邊界狀態就是 如果i==j,那麼dp[i][j]=0. 如果i和j的距離在聰聰的一步之內,那麼dp[i][j]=1.
記憶化搜尋一下即可。
# include # includeview code# include
# include
# include
# include
# include
# include
# include
# include
# include
using
namespace
std;
# define lowbit(x) ((x)&(-x))
# define pi
3.1415926535
# define eps 1e-9
# define mod
100000007
# define inf
1000000000
# define mem(a,b) memset(a,b,
sizeof
(a))
# define for(i,a,n)
for(int i=a; i<=n; ++i)
# define fo(i,a,n)
for(int i=a; ii)
# define bug puts("h
");# define lch p
<<1
,l,mid
# define rch p
<<1|1,mid+1
,r# define mp make_pair
# define pb push_back
typedef pair
pii;
typedef vector
vi;# pragma comment(linker,
"/stack:1024000000,1024000000")
typedef
long
long
ll;int
scan()
void out(int
a)
if(a>=10) out(a/10
); putchar(a%10+'0'
);}const
int n=1005;//
code begin...
struct edgeedge[n<<1
];int to[n][n], f[n], dee[n], head[n], cnt=1
, n, vis[n];
double
dp[n][n];
bool
mark[n][n];
queue
q;void add_edge(int u, int
v)void
bfs()
q.push(u); vis[u]=vis[v]+1
;
if (vis[u]<=2) f[u]=u;
else f[u]=f[v];}}
for(j,
1,n) to[i][j]=f[j];
}}double dfs(int x, int
y)int
main ()
bzoj 1415 聰聰和可可 期望
可以先預處理出當聰聰在 i 點,可可在 j 點時,聰聰下一步到達的點的編號,記為p i,j bfs即可。設f i,j 表示聰聰在 i,可可在 j 時的期望步數,w i,j 為與i相鄰的第 j 個點編號,t i 為 i 點的度數,則有f i,j t i k 1f p p i j j w j,k f p...
bzoj1415 聰聰和可可
對於任意一對位置x,y我們可以找到聰聰的行走方案。這個可以bfs跑 然後我們用f x,y 表示聰聰在x,可可在y抓住的期望時間,於是轉移方程是 if x y f x y 0,if x走兩步能到y f x y 1,else f x y sigma f x nxtpos y nxtpos 1 d y 1...
BZOJ1415 Noi2005 聰聰和可可
資料的第1行為兩個整數n和e,以空格分隔,分別表示森林中的景點數和連線相鄰景點的路的條數。第2行包含兩個整數c和m,以空格分隔,分別表示初始時聰聰和可可所在的景點的編號。接下來e行,每行兩個整數,第i 2行的兩個整數ai和bi表示景點ai和景點bi之間有一條路。所有的路都是無向的,即 如果能從a走到...