uva-10828 期望dp+gauss
阿新 • • 發佈:2018-11-05
題意:給你一個有向圖,從1號節點出發,問經過某個點的期望次數。
思路:傳遞閉包寫錯wa到哭。設 dp[i]為經過i點期望
dp[v]=dp[u1]*p1+dp[u2]*p2+....(對於第一個點應該再+1)
將每個dp看做變數,就可以構成n*n的矩陣比如樣例1構成矩陣如下
-1 1 0 -1
0.5 -1 0 0
0 0.5 -1 0
用高斯消元解就可以,對於有解得dp直接輸出就可以,對於無窮的,與他相關的點也無窮,也就是他傳遞閉包能到的點。
程式碼一:
#include<bits/stdc++.h> using namespace std; #define eps 1e-9 const int MAXN=110; double a[MAXN][MAXN], x[MAXN]; int equ, var; int n; int gauss(){ int i, j, k, col, max_r; for(k=0, col=0; k<equ&&col<var; k++, col++){ max_r=k; for(i=k+1; i<equ; i++) if(fabs(a[i][col])>fabs(a[max_r][col])) max_r=i; if(fabs(a[max_r][col])<eps) return 0; if(k!=max_r){ for(j=col; j<var; j++) swap(a[k][j], a[max_r][j]); swap(x[k], x[max_r]); } x[k]/=a[k][col]; for(j=col+1; j<var; j++) a[k][j]/=a[k][col]; a[k][col]=1; for(i=0;i<equ; i++) if(i!=k){ x[i]-=x[k]*a[i][col]; for(j=col+1; j<var; j++) a[i][j]-=a[k][j]*a[i][col]; a[i][col]=0; } } return 0; } vector<int> G[110]; int dgr[110]; bitset<110> inf; int mp[110][110]; int main(){ int cas=0; while(~scanf("%d", &n) && n){ memset(a, 0, sizeof a); memset(x, 0, sizeof x); memset(mp, 0, sizeof mp); inf.reset(); for(int i=0; i<n; i++) G[i].clear(), dgr[i]=0, a[i][i]=-1; int u, v; while(scanf("%d%d", &u, &v)&&(u||v)){ u--; v--; G[u].push_back(v); mp[u][v]=1; dgr[u]++; } equ=n, var=n; x[0]=-1; for(int i=0; i<n; i++){ for(int j=0; j<G[i].size(); j++){ int v=G[i][j]; a[v][i]+=1./dgr[i]; } } for(int k=0; k<n; k++) for(int i=0; i<n; i++) for(int j=0; j<n; j++) if(mp[i][k] && mp[k][j]) mp[i][j]=1; gauss(); for(int i=0; i<n; i++){ if(fabs(x[i])>eps && fabs(a[i][i])<eps) inf[i]=1; if(inf[i]) for(int j=0; j<n; j++) if(mp[i][j]) inf[j]=inf[i]; } printf("Case #%d:\n", ++cas); int Q, p; scanf("%d", &Q); while(Q--){ scanf("%d", &p); p--; if(inf[p]) puts("infinity"); else{ printf("%.3lf\n", fabs(x[p])); } } } return 0; }
程式碼二:
#include<bits/stdc++.h> using namespace std; #define eps 1e-9 const int MAXN=110; double a[MAXN][MAXN], x[MAXN]; int equ, var; int n; int gauss(){ int i, j, k, col, max_r; for(k=0, col=0; k<equ&&col<var; k++, col++){ max_r=k; for(i=k+1; i<equ; i++) if(fabs(a[i][col])>fabs(a[max_r][col])) max_r=i; if(fabs(a[max_r][col])<eps) return 0; if(k!=max_r){ for(j=col; j<var; j++) swap(a[k][j], a[max_r][j]); swap(x[k], x[max_r]); } x[k]/=a[k][col]; for(j=col+1; j<var; j++) a[k][j]/=a[k][col]; a[k][col]=1; for(i=0;i<equ; i++) if(i!=k){ x[i]-=x[k]*a[i][col]; for(j=col+1; j<var; j++) a[i][j]-=a[k][j]*a[i][col]; a[i][col]=0; } } return 0; } vector<int> G[110]; int dgr[110]; bitset<110> inf; int main(){ int cas=0; //freopen("E:/in.txt", "r", stdin); //freopen("E:/example.txt", "w", stdout); while(~scanf("%d", &n) && n){ memset(a, 0, sizeof a); memset(x, 0, sizeof x); inf.reset(); for(int i=0; i<n; i++) G[i].clear(), dgr[i]=0, a[i][i]=-1; int u, v; while(scanf("%d%d", &u, &v)&&(u||v)){ u--; v--; G[u].push_back(v); dgr[u]++; } equ=n, var=n; x[0]=-1; for(int i=0; i<n; i++){ for(int j=0; j<G[i].size(); j++){ int v=G[i][j]; a[v][i]+=1./dgr[i]; } } gauss(); for(int i=n-1; i>=0; i--){ if(fabs(x[i])>eps && fabs(a[i][i])<eps) inf[i]=1; for(int j=i+1; j<n; j++) if(fabs(a[i][j])>eps && inf[j]) inf[i]=1; } printf("Case #%d:\n", ++cas); int Q, p; scanf("%d", &Q); while(Q--){ scanf("%d", &p); p--; if(inf[p]) puts("infinity"); else{ printf("%.3lf\n", fabs(x[p])); } } } return 0; } /* 3 1 3 3 2 0 0 3 1 2 3 5 1 2 3 5 2 4 3 1 4 2 2 3 4 5 0 0 5 1 2 3 4 5 */