1. 程式人生 > >HDU 5097 Page Rank(模擬,矩陣運算)

HDU 5097 Page Rank(模擬,矩陣運算)

題意:有點難讀懂,我是跟著圖YY的。

輸入一個N*N的01矩陣A,先將它轉換成類似圖片裡面的矩陣S。

具體做法是,對於第i行,求出1的個數cnt,然後如果A[i][j]是1,B[j][i]就等於1/cnt,否則等於0。注意這裡i , j前後是相反的。

然後根據題目裡面的公式求出G矩陣,U是一個全1的矩陣。

跟著就是搞一個q的N行1列的矩陣,按照題目要求迭代就行。

當然這裡有個讓人納悶的地方,就是q的初始值的問題,貌似沒說。我就隨便全部設成1過了,不知道是不是無論什麼初始值最後都會收斂到同一個地方還是怎麼樣。

#include<cstdio>
#include<cstring>
#include<cmath>
const double alpha = 0.85;
const double eps = 1e-10;
const int N = 3010;
int n;
double mat[N][N], q[2][N];
inline double sqr(double x){
    return x*x;
}
bool ok(){
    double s = 0.0;
    for(int i=0; i<n; i++)  s += sqr(q[0][i]-q[1][i]);
    return fabs(s)<eps;
}
char s[N];
int main(){
    while(~scanf("%d", &n)){
        double b = (1.0-alpha)/n;
        for(int i=0; i<n; i++){
            scanf("%s", s);
            int m = 0;
            for(int j=0; j<n; j++)  m += s[j]-'0';
            for(int j=0; j<n; j++){
                mat[j][i] = s[j]=='0'?0.0:(1.0/m);
                mat[j][i] = mat[j][i]*alpha + b;
            }
            q[1][i] = 0.0;
            q[0][i] = 1.0;
        }
        bool f = 0;
        while(!ok()){
            for(int i=0; i<n; i++){
                q[f^1][i] = 0.0;
                for(int j=0; j<n; j++){
                    q[f^1][i] += mat[i][j] * q[f][j];
                }
            }
            f^=1;
        }
        for(int i=0; i<n; i++){
            if(i)   putchar(' ');
            printf("%.2f", q[f][i]);
        }
        puts("");
    }
    return 0;
}