NOI2005聪明与可可

来自蒟蒻XXJ的学习记录

可以看《浅析竞赛中一类数学期望问题的解决方法》汤可因

#include<bits/stdc++.h>
#define mem(i,j) memset(i,j,sizeof(i))
#define GO(i,here) for(int i=head[here];i!=-1;i=nex[i])
using namespace std;
const int MAXN=1024;
const int MAXE=2048;
inline int in(){
	int a(0);char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') a=(a<<1)+(a<<3)+c-'0',c=getchar();
	return a;
}
int n,e,c,m;
int head[MAXN],to[MAXE],nex[MAXE],top1;
int p[MAXN][MAXN],vis[MAXN];
double f[MAXN][MAXN],t[MAXN];
queue<int> q;
void bfs(int s){
	q.push(s);mem(vis,-1);
	vis[s]=0;
	while(!q.empty()){
		int here=q.front();q.pop();
		GO(i,here){
			if(vis[to[i]]==vis[here]+1) p[s][to[i]]=min(p[s][to[i]],p[s][here]);
			if(vis[to[i]]>=0) continue;
			p[s][to[i]]=p[s][here];
			if(s==here) p[s][to[i]]=to[i];
			vis[to[i]]=vis[here]+1;
			q.push(to[i]);
		}
	}
}
void add(int a,int b){
	nex[top1]=head[a];head[a]=top1;to[top1++]=b;
	nex[top1]=head[b];head[b]=top1;to[top1++]=a;
}
double dp(int a,int b){
	if(f[a][b]) return f[a][b];
	if(a==b) return 0;
	if(p[a][b]==b||p[p[a][b]][b]==b) return f[a][b]=1;
	double tot=dp(p[p[a][b]][b],b);
	GO(i,b){
		int tmp=to[i];
		tot+=dp(p[p[a][b]][b],to[i]);
	}
	f[a][b]=tot/(t[b]+1.0)+1.0;
	return f[a][b];
}
void input(){
	mem(head,-1);
	n=in();e=in();
	c=in();m=in();
	for(int i=1;i<=e;i++){
		int a,b;
		a=in();b=in();
		add(a,b);
		++t[a];++t[b];
	}
	for(int i=1;i<=n;i++)
		bfs(i);
}
void xxj(){
	cout<<fixed<<setprecision(3)<<dp(c,m)<<endl;
}
int main(){
	input();
	xxj();
	return 0;
}
posted @ 2017-03-30 09:30  Xiaojian_xiang  阅读(173)  评论(0编辑  收藏  举报