1. 程式人生 > >[Luogu2973][USACO10HOL]趕小豬

[Luogu2973][USACO10HOL]趕小豬

get tdi code 一個 algorithm www next || blog

Luogu

sol

首先解釋一波這道題無重邊無自環
\(f_i\)表示\(i\)點上面的答案。
方程
\[f_u=\sum_{v,(u,v)\in E}(1-\frac PQ)\frac{f_v}{du_v}\]
\(f_1\)的那個方程加一個\(\frac PQ\)常數項

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N = 305;
int gi()
{
    int x=0,w=1
;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=0,ch=getchar(); while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } struct edge{int
to,next;}a[N*N<<1]; int n,m,head[N],cnt; double p,f[N][N],du[N],sol[N]; int main() { n=gi();m=gi(); p=(double)gi()/(double)gi(); for (int i=1,u,v;i<=m;i++) { u=gi();v=gi(); a[++cnt]=(edge){v,head[u]};head[u]=cnt; a[++cnt]=(edge){u,head[v]};head[v]=cnt; du[u]+=1.0
;du[v]+=1.0; } f[1][n+1]=p; for (int u=1;u<=n;u++) { f[u][u]=1; for (int e=head[u];e;e=a[e].next) f[u][a[e].to]-=(1-p)/du[a[e].to]; } for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) for (int k=n+1;k>=i;k--) f[j][k]-=f[i][k]*f[j][i]/f[i][i]; for (int i=n;i;i--) { sol[i]=f[i][n+1]; for (int j=n;j>i;j--) sol[i]-=f[i][j]*sol[j]; sol[i]/=f[i][i]; } for (int i=1;i<=n;i++) printf("%.9lf\n",sol[i]); return 0; }

[Luogu2973][USACO10HOL]趕小豬