2021.1.4 省选训练 CF113D Museum

暴力卡常

//可以加火车头(亲测用处不大) 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 23//开大会TLE(?) 
#define M 550
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m;
double a[N],b[N],out[N],f[2][N][N],ans[N];
double E=1e-15;
int head[N],nxt[M],v[M],cnt;
inline void add(int x,int y)
{
	v[++cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
}
inline void DP(int s1,int s2,int x,int y)
{
	double tmp[2][2];//减少乘法运算 
	tmp[0][0]=b[s1]*b[s2]*f[x][s1][s2];//期望的运算方法(错) 
	tmp[0][1]=b[s1]*a[s2]*f[x][s1][s2];
	tmp[1][0]=a[s1]*b[s2]*f[x][s1][s2];
	tmp[1][1]=a[s1]*a[s2]*f[x][s1][s2];
	for(int i=head[s1];i;i=nxt[i])
	    for(int j=head[s2];j;j=nxt[j])
	        f[y][v[i]][v[j]]+=tmp[0][0];
	for(int i=head[s1];i;i=nxt[i]) f[y][v[i]][s2]+=tmp[0][1];
	for(int j=head[s2];j;j=nxt[j]) f[y][s1][v[j]]+=tmp[1][0];
	f[y][s1][s2]+=tmp[1][1];
}
int main()
{
	int s1,s2;
    n=read();m=read();s1=read();s2=read();
    if(n==1){printf("1\n");return 0;}//注意特判(错) 
    if(s1==s2)
    {
    	for(int i=1;i<=n;i++)
    	    if(i==s1) printf("1 ");
    	    else printf("0 ");
    	return 0;
	}
    int x,y;
    for(int i=1;i<=m;i++)
	{
		x=read();y=read();
		add(x,y),add(y,x);
		out[x]+=1.0;
		out[y]+=1.0;
	}
    for(int i=1;i<=n;i++) scanf("%lf",&a[i]),b[i]=(1.0-a[i])/out[i];
    x=0;y=1;
    f[x][s1][s2]=1.0;
    int t=150000;
    while(t--)//x->y  推表式 
    {
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=n;j++)
    	    {
    	    	if(f[x][i][j]<=E) continue;//忽略过小的精度误差(卡精度) 
    	    	if(i==j) continue;
    	        DP(i,j,x,y);
			}
    	for(int k=1;k<=n;k++) ans[k]+=f[y][k][k];
		x^=1;y^=1;
    	memset(f[y],0,sizeof(f[y]));//注意清空(错) 
	}
	for(int i=1;i<=n;i++) printf("%.12lf ",ans[i]);//需要手动调整输出精度 
	return 0;
}

  

高斯消元(待填)

posted @ 2021-01-04 18:48  骑着蜗牛去战斗  阅读(10)  评论(0编辑  收藏  举报