题目大意:给定n个点,一些点之间有电阻相连,求1~n的等效电阻
首先我们设电流为1A 终点电势为零 点i的电势为Ui
由于电流是流 显然对于每个点(点1和点n除外) 有总流入等于总流出 即
Σ(Ui-Uj)/Rij=0 (i!=1,i!=n)
Σ(U1-Uj)/R1j=1
Σ(Un-Uj)/Rnj=-1
Un=0
联立方程组高斯消元即可 最后输出点1的电势就是答案
注意自环要无视 重边要用倒数和缩成一条 我用了电导所以直接加就行
科普:电导 电阻的倒数 G=1/R=I/U 在两个点之间并联多个电阻时G总=ΣGi 两点间断路时G=0 短路时G=+∞
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 510 using namespace std; int n,m; double map[M][M],f[M][M],ans[M]; void Initialize() { memset(map,0,sizeof map); memset(f,0,sizeof f); } void Gauss_Elimination() { int i,j,k; for(i=1;i<=n;i++) { k=0; for(j=i;j<=n;j++) if( fabs(f[j][i])>fabs(f[k][i]) ) k=j; for(j=1;j<=n+1;j++) swap(f[i][j],f[k][j]); for(j=i+1;j<=n;j++) { double temp=f[j][i]/f[i][i]; for(k=i;k<=n+1;k++) f[j][k]-=f[i][k]*temp; } } for(i=n;i;i--) { for(j=n;j>i;j--) f[i][n+1]-=ans[j]*f[i][j]; ans[i]=f[i][n+1]/f[i][i]; } } int main() { int i,j,x,y,r; while(cin>>n>>m) { Initialize(); for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&r); map[x][y]+=1.0/r;map[y][x]+=1.0/r; } for(i=1;i<=n;i++) for(j=1;j<=n;j++) f[i][i]+=map[i][j],f[i][j]-=map[i][j]; f[1][n+1]=1; f[n][n+1]=-1; f[n][n]+=1.0; Gauss_Elimination(); printf("%.2lf\n",ans[1]); } }
时间: 2024-12-13 10:19:06