首先每条边至多走两遍,可以选出一条最长的链,这条链上的所有边走一遍,其他边走两边。
那么答案就是 2|E|−|P| 2 | E | − | P | 其中 E E 是边集, 是最长的链
这个的期望就是 2E(|E|)−E(|P|) 2 E ( | E | ) − E ( | P | )
E(|E|) E ( | E | ) 可以枚举每条边,求这条边存在的概率
E(|P|) E ( | P | ) 可以枚举点对,这对点对的距离乘上它为最长链的概率就是答案
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int N=310;
int n,m,k,cnt,G[N*10],sp[N*10],g[N][310];
struct edge{
int t,nx;
}E[20*N];
inline void addedge(int x,int y){
//cerr<<x<<' '<<y<<endl;
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt;
}
vector<int> s;
int dis[2510][2510],sz[N*10],d[N][N];
void dfs(int x,int f,int s,int d){
dis[s][x]=d;
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=f) dfs(E[i].t,x,s,d+1);
}
double ans;
inline double C(int x,int y,int kk=k){
double ret=1;
for(int i=0;i<kk;i++)
ret=ret*(x-i)/(double)(y-i);
return ret;
}
void pfs(int x,int f){
sz[x]=sp[x];
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=f) pfs(E[i].t,x),sz[x]+=sz[E[i].t];
if(f){
int a=sz[x],b=m-a;
double cur=0;
if(a>=k) cur+=C(a,m);
if(b>=k) cur+=C(b,m);
ans+=1-cur;
}
}
inline double EE(){
pfs(1,0);
return ans;
}
double c[N][N];
inline double PP(){
double ret=0; int t=0;
for(int i=0;i<s.size();i++)
for(int j=0;j<s.size();j++)
d[i][j]=dis[s[i]][s[j]];
for(int i=0;i<s.size();i++)
for(int j=i+1;j<s.size();j++){
int cnt=0;
for(int k=0;k<s.size();k++){
if(k==i || k==j) continue;
int flg=0;
if(d[i][k]>d[i][j] || (d[i][k]==d[i][j] && k<j)) flg=1;
if(d[j][k]>d[i][j] || (d[j][k]==d[i][j] && k<i)) flg=1;
cnt+=flg;
}
cnt=m-cnt-2;
if(cnt<k-2) continue;
ret+=d[i][j]*c[cnt][k-2]/c[m][k];
}
//ret*=(m-k+1)*(m-k+2)/(double)k/(k-1);
return ret;
}
class Orienteering{
public:
double expectedLength(vector<string> field,int K){
k=K;
for(int i=0;i<field.size();i++)
for(int j=0;j<field[i].size();j++){
if(field[i][j]=='#') continue;
g[i][j]=++n;
if(i && field[i-1][j]!='#') addedge(g[i-1][j],n);
if(j && field[i][j-1]!='#') addedge(g[i][j-1],n);
if(field[i][j]=='*') sp[n]=1,s.push_back(n);
}
m=s.size();
for(int i=0;i<=m;i++){
c[i][0]=1;
for(int j=1;j<=i;j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
for(int i=1;i<=n;i++) dfs(i,0,i,0);
return 2*EE()-PP();
}
}Main;
int main(){
vector<string> f= {"**##*.**#..#.*...*#...*#..#.##..#..#.#*...#.##*##.",
".#..###..#..#.#.##..#.#.*#.*..#..#.#*..##.#*...*..",
"..#.....###.#*.##..#.#.#*..#.#..#....#..#...#*####",
".#.##*#.*#..#*#*.#.#...*.#.*#.#.##.#*.##.#.#..*...",
"..*.*#*.###.#..#.#..##.##.*#..#.....#.....#..#.#.#",
".#.##.#..##..*#..#.#...#*##*#*..#.#.#.#.##.##.#.#*",
"..##....#..#.#*#...*.##...#.#.####...#.#*.....#...",
".#.*#.##.*#*.#*.#.#.#..#.#..#.#*#.###..##.##.#.##*",
".*.#*..*.#.#...#.*##.#.**.#.*...**..*#..#.#.#*.#..",
".#*.#*##....##.#.#*..*.###.#.##.##.#.#.#....#.#*.#",
"*.#..#*#.#*#*....#.#.#..*#**...##.#.#.**#*##.*.#..",
".#*.##..##..##.#.#..#.#.###.###...#...#*#..##*#.#.",
"#..#*.#..*.###..#.#...#.###.#.#*#.#.#**##.#...*.#*",
"..#..#.#.##.#..#.**.##*#.#**.**..#.#..#...#.##*#..",
".#*#.#.*..#.*#...#.#...#...#.##.#..*#*.##*....###.",
".*.#.#.#.#*#..*##.**.##*##..#.*#.#*###..*.#.##.#..",
".#......#...#.#.*#.#.#..#..#.#*#....#*.#*#.*#..*.#",
"#..####..#*#...#*.#..#.###...#.#.#.###*#..##*##.#.",
".#.*..#.#...#.#..#.##...#..#.#.#.#.###..##..*.*.*.",
".#.#.#.#..##.*..#.*.#.##.#..##*...#.#..#.#.##.#.##",
".#..#*.#.#..#.##..##..#.*..#.*#.#...##....#...###.",
".#.#.#.#*.#.#..#.#..#..#.#.*#...#.##...#.##.##.*..",
".#...#.#.##.#.#..*#.*#..###..#.#.#*###.##...#*.##.",
".#.##.*.......*.#.*#.#.#*###..*...*..#.*.##.#.#..#",
"...###*####*#.#..##*...#..#..##.#.#.#..##*#*.*.*#.",
"#.#.#....*#..#.#.#.#.##..#*.#...#..#.#*#...#.##.*.",
"..*.#*##.#.#*#.###...#..##.#.#.#*###*#.*#.#.*###.#",
"##*##..##...#.....##.#.#.**#..#*.....##.#..#*.#.*.",
".....#.*.##..##.##*.*#...#.#.#.##.#*#.**..#..#.#.#",
"##.#.#*##.#.#.*.*.#.#*#.#.#....*...#*##*##.#....#.",
"*.**#**....*..##.#*.*.**..##.###.##.....##...##.**",
"#.####.##*#*##..#.*#*#.##*...#.##..#.##....#*..##.",
"....#...##.#...#*.#..##.##.#*..*.#....##.#.*##...#",
"#.#..*##*..#.#..#..#..#*....#.##..##.#*##.##.*##..",
"..#.#*.*.##.#.#*#.#*##.###.##...#............#*.#.",
"#.#.##.#....*....*..##..*#.#.#.###.#.#.#.###..#..#",
".#**..#*#.#*#*#.#.#...*##....##.#*..#..#*..*#..#..",
"...#*#.....#..#.#..#*#.*##.#..#.#.##..#.*#*#.#...#",
".#*.###.#.#.#.#.*#*##.##..#.#*..#...#.#.#..#*.*#..",
"#*.#.#.#..#..#..#....*#.*##..##.#.#..#...##.#.#..#",
"*.#..#..#...#..##.#*#..#.#*#.#.#.###..#.#*...#.#..",
"#...#.#...#.#.#..#.*.#*.....**.*..#*##.#*.##....##",
"#*#....#*#..#.*.###*#..#*##.##.#.#...#.*.##.##.##.",
"..##*##*..#*#.#..#*.*##*.##.#...#.#.#.#.#..*#.##..",
"#...#*##.#*#**.##.*#.*.##..*.#*#**....#**##...*.*#",
"*#.##......*#.##.#.#.##**.#.#.#.#.#.##..#...#*#*#*",
"*....##.#.#..#.....#..##.#....*....#.#.##.#.#.##**",
"#.##*#...#..#.#.##..#..##.##.##.##........##.#*#.#",
"..#...#.#*#*..*#..*#.*#.#......##.#.#.#*#..#..****",
".###.#..#...#.#..#..#.#...#.#.#...**.#..*#*.*##*#."};
int K=150;
printf("%.9lf\n",Main.expectedLength(f,K));
for(;;);
}