题意:给出一个图,无重边,边权为电阻大小,求1~n的等效电阻。
要知道等效电阻,很显然要知道电流和电势差。
电阻必然是确定的,那么电势差会随流过电流的大小变化,为了方便,不妨设流入1节点的电流为1,n节点的电势为0。
每个节点的电势视为未知数,那么根据KCL,流入节点的电流必然等于流出节点的电流,列出n个方程。结果就是电势差/I。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #define EPS 1e-8 6 #define MAXN 55 7 using namespace std; 8 double r[MAXN][MAXN], g[MAXN][MAXN], u[MAXN]; 9 int n; 10 void Gauss() { 11 int i, j, k; 12 double tmp; 13 for (i = 0; i < n; i++) { 14 tmp = 0; 15 for (j = i; j < n; j++) { 16 if (fabs(g[j][i]) > tmp) { 17 tmp = fabs(g[j][i]); 18 k = j; 19 } 20 } 21 if (k != i) { 22 for (j = i; j <= n; j++) 23 swap(g[k][j], g[i][j]); 24 } 25 for (j = i + 1; j < n; j++) { 26 if (fabs(g[j][i]) > EPS) { 27 tmp = g[j][i] / g[i][i]; 28 for (k = i; k <= n; k++) 29 g[j][k] -= g[i][k] * tmp; 30 } 31 } 32 } 33 for (i = n - 1; i >= 0; i--) { 34 if (fabs(g[i][i]) < EPS) 35 u[i] = 0; 36 else { 37 tmp = 0; 38 for (j = i + 1; j < n; j++) 39 tmp += g[i][j] * u[j]; 40 tmp = g[i][n] - tmp; 41 u[i] = tmp / g[i][i]; 42 } 43 } 44 } 45 int main() { 46 int c, ca = 1; 47 int q, x, y, i, j; 48 double tmp; 49 scanf("%d", &c); 50 while (c--) { 51 scanf("%d%d", &n, &q); 52 memset(r, 0, sizeof(r)); 53 memset(g, 0, sizeof(g)); 54 while (q--) { 55 scanf("%d%d%lf", &x, &y, &tmp); 56 x--, y--; 57 r[x][y] = r[y][x] = tmp; 58 } 59 for (i = 0; i < n; i++) { 60 for (j = 0; j < n; j++) { 61 if (r[i][j]) { 62 g[i][j] += 1 / r[i][j]; 63 g[i][i] -= 1 / r[i][j]; 64 } 65 } 66 } 67 g[0][n] = -1, g[n - 1][n] = 1; 68 Gauss(); 69 printf("Case #%d: %.2lf\n", ca++, u[0] - u[n - 1]); 70 } 71 return 0; 72 }