Description
There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is no two or more flight lines start from the same grid.
Please help Hzz calculate the expected dice throwing times to finish the game.
Input
Each test case contains several lines.
The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).
Then M lines follow, each line contains two integers Xi,Yi(1≤Xi<Yi≤N).
The input end with N=0, M=0.
Output
飛行棋盤長度爲N+1,標號從0到N,中間有M條飛行線,可以從Xi直接飛到Yi(可以連續飛),現在丟骰子,問走到>=N的投擲期望次數。
範圍:
N<=10W,M<=1000
解法:
很明顯的概率DP,設DP[I]爲當前站在I位置,走到頭的期望投擲數爲DP[I],顯然DP[>=N]=0,目標爲DP[0]
方程爲 DP[I]=Σ (1/6 * DP[J]) ,其中J分別投出1-6會到達的點,這個點可以通過並查集求出。
代碼:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int n,m;
int f[100100];
int find(int x){
while(x!=f[x]){
f[x]=f[f[x]];
x=f[x];
}
return x;
}
void connec(int x,int y){
int i=find(x);
int j=find(y);
if(i==j)return;
if(i>j)swap(i,j);
f[i]=j;
}
double dp[100100];
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0)break;
rep(i,1,n+10)f[i]=i;
rep(i,1,m){
int x,y;
scanff(x);
scanff(y);
connec(x,y);
}
rep(j,0,10)dp[n+j]=0;
drep(i,n-1,0){
dp[i]=1.0;
rep(j,1,6){
dp[i]+=dp[find(i+j)]/6.0;
}
}
printf("%.4lf\n",dp[0]);
}
return 0;
}