【系列】高斯消元
bzoj 1013
题目大意:
给出$n$维球体上的$n+1$个点,求球心
思路:
设球心坐标$(x_1,x_2,x_3 \cdots x_n)$
则对于任意两个点$(a_1,a_2 \cdots a_n),(b_1,b_2 \cdots b_n)$,得到$(x_1-a_1)^2+(x_2-a_2)^2 \cdots (x_n-a_n)^2=(x_1-b_1)^2+(x_2-b_2)^2 \cdots (x+n-b_n)^2$
移项后得到$2(a_1-b_1)x_1+2(a_2-b_2)x_2 \cdots 2(a_n-b_n)x_n = {a_1}^2-{b_1}^2+{a_2}^2-{b_2}^2 \cdots {a_n}^2-{b_n}^2$
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #define ll long long 12 #define db double 13 #define inf 2139062143 14 #define MAXN 200100 15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i) 16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i) 17 #define ren for(register int i=fst[x];i;i=nxt[i]) 18 #define Fill(x,t) memset(x,t,sizeof(x)) 19 #define pls(a,b) (a+b)%MOD 20 #define mns(a,b) (a-b+MOD)%MOD 21 #define mul(a,b) (1LL*(a)*(b))%MOD 22 using namespace std; 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 27 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 28 return x*f; 29 } 30 int n;db a[15][15],g[15][15]; 31 db sqr(db x) {return x*x;} 32 void Gauss() 33 { 34 int pos;rep(i,0,n-1) 35 { 36 pos=n;rep(j,i,n-1)if(fabs(a[j][i])>fabs(a[pos][i])) pos=j; 37 if(pos!=i) rep(j,0,n) swap(a[i][j],a[pos][j]); 38 dwn(j,n,i) rep(k,i+1,n-1) a[k][j]-=a[k][i]/a[i][i]*a[i][j]; 39 } 40 dwn(i,n-1,0) {rep(j,i+1,n-1) a[i][n]-=a[j][n]*a[i][j];a[i][n]/=a[i][i];} 41 } 42 int main() 43 { 44 n=read();rep(i,0,n) rep(j,0,n-1) scanf("%lf",&g[i][j]); 45 rep(i,1,n) rep(j,0,n-1) 46 a[i-1][j]=2*(g[i][j]-g[i-1][j]),a[i-1][n]+=sqr(g[i][j])-sqr(g[i-1][j]); 47 Gauss();rep(i,0,n-1) printf("%.3lf ",a[i][n]); 48 }
bzoj 3270
题目大意:
一开始两个人在$s,t$两个点,当一个人在$i$点时,有$p_i$的概率不动,有$1-p_i$的概率向相邻的点等概率移动
如果两个人在一个点相遇就停止,求他们在每个点相遇的概率
思路:
设$f(i,j)$表示两个人在$i,j$的概率,设$x,y$分别为$i,j$的前驱
很容易得到方程$f(i,j)=\sum (i==x?p_x:\frac{1-p_x}{d_x})*(j==y?p_y:\frac{1-p_y}{d_y})$
对于$f(s,t)$概率为$1$,其余为$0$,一共$n^2$个方程消元即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #define ll long long 12 #define db double 13 #define inf 2139062143 14 #define MAXN 200100 15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i) 16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i) 17 #define ren for(register int i=fst[x];i;i=nxt[i]) 18 #define Fill(x,t) memset(x,t,sizeof(x)) 19 #define pls(a,b) (a+b)%MOD 20 #define mns(a,b) (a-b+MOD)%MOD 21 #define mul(a,b) (1LL*(a)*(b))%MOD 22 using namespace std; 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 27 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 28 return x*f; 29 } 30 int n,m,ss,tt,mp[35][35],d[35];db a[410][410],p[35]; 31 void Gauss(int n) 32 { 33 int pos;rep(i,0,n-1) 34 { 35 pos=n;rep(j,i,n-1)if(fabs(a[j][i])>fabs(a[pos][i])) pos=j; 36 if(pos!=i) rep(j,0,n) swap(a[i][j],a[pos][j]); 37 dwn(j,n,i) rep(k,i+1,n-1) a[k][j]-=a[k][i]/a[i][i]*a[i][j]; 38 } 39 dwn(i,n-1,0) {rep(j,i+1,n-1) a[i][n]-=a[j][n]*a[i][j];a[i][n]/=a[i][i];} 40 } 41 inline int t(int x,int y) {return (x-1)*n+y-1;} 42 int main() 43 { 44 n=read(),m=read(),ss=read(),tt=read();int x,y; 45 while(m--) x=read(),y=read(),mp[x][y]=mp[y][x]=1,d[x]++,d[y]++; 46 rep(i,1,n) scanf("%lf",&p[i]),mp[i][i]=1;a[t(ss,tt)][n*n]=1.0; 47 rep(i,1,n) rep(j,1,n) 48 { 49 a[t(i,j)][t(i,j)]=1.0; 50 rep(x,1,n) rep(y,1,n) if(x^y&&mp[x][i]*mp[y][j]) 51 a[t(i,j)][t(x,y)]-=1.0*(i==x?p[x]:(1.0-p[x])/d[x])*(j==y?p[y]:(1.0-p[y])/d[y]); 52 } 53 Gauss(n*n);rep(i,1,n) printf("%.6lf ",a[t(i,i)][n*n]); 54 }