题解:P2011 计算电压

最后更新于 2025-08-03 09:10:50
作者
分类 题解

话不多说,直接上代码

#include

#include

#include

#include

using namespace std;

const double EPS = 1e-8;

int main() { //主函数 ios::sync_with_stdio(false); cin.tie(nullptr);

int n, m, k, q;
cin >> n >> m >> k >> q;

vector<double> voltage(n + 1, 0.0);
vector<vector<double>> conductance(n + 1, vector<double>(n + 1, 0.0));

for (int i = 0; i < k; ++i) {
    int node;
    double u;
    cin >> node >> u;
    voltage[node] = u;
}

for (int i = 0; i < m; ++i) {
    int v, w;
    double r;
    cin >> v >> w >> r;
    double g = 1.0 / r;
    conductance[v][w] += g;
    conductance[w][v] += g;
}

int matrix_size = n;
vector<vector<double>> matrix(matrix_size, vector<double>(matrix_size + 1, 0.0));

for (int i = 1; i <= n; ++i) {
    if (abs(voltage[i]) > EPS) {
        int row = i - 1;
        matrix[row][row] = 1.0;
        matrix[row][matrix_size] = voltage[i];
        continue;
    }

    double total_g = 0.0;
    for (int j = 0; j <= n; ++j) {
        total_g += conductance[i][j];
    }

    matrix[i - 1][i - 1] = total_g;

    for (int j = 1; j <= n; ++j) {
        if (i != j && conductance[i][j] > EPS) {
            matrix[i - 1][j - 1] = -conductance[i][j];
        }
    }
}

for (int col = 0; col < matrix_size; ++col) {
    int max_row = col;
    for (int row = col + 1; row < matrix_size; ++row) {
        if (abs(matrix[row][col]) > abs(matrix[max_row][col])) {
            max_row = row;
        }
    }

    swap(matrix[col], matrix[max_row]);

    for (int row = col + 1; row < matrix_size; ++row) {
        double factor = matrix[row][col] / matrix[col][col];
        for (int c = col; c <= matrix_size; ++c) {
            matrix[row][c] -= factor * matrix[col][c];
        }
    }
}

for (int row = matrix_size - 1; row >= 0; --row) {
    if (abs(matrix[row][row]) < EPS) continue;

    voltage[row + 1] = matrix[row][matrix_size];
    for (int col = row + 1; col < matrix_size; ++col) {
        voltage[row + 1] -= matrix[row][col] * voltage[col + 1];
    }
    voltage[row + 1] /= matrix[row][row];
}

cout << fixed << setprecision(2);
for (int i = 0; i < q; ++i) {
    int a, b;
    cin >> a >> b;
    double diff = voltage[a] - voltage[b];
    cout << diff << endl;
}

return 0;

}