Resistance
题意:
给出一个由n个节点和m个二元电阻元件组成的电路,求问节点1到节点n的等效电阻。
解法:
应用电子电路分析中的基尔霍夫定律,对于每一个点有流量平衡,得
对于点$x$有 $$I_{出} + \sum_{<i,x>∈|E|}{\frac{U_x-U_i}{R_{x,i}}} = I_{入}$$
规定从点1流入$1A$的电流,从点n流出$1A$的电流,得到n个关于$U_i$的方程。
注意到n个方程最大线性无关组为 n-1个方程,解出来是$x = k* \eta + \xi$,从而要引入一个新的方程。
(因为限制流入1的电流是$1A$的方程是多余的)
只要将点1的方程改成 $U_1 = 0V$ 即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <cmath> 6 7 #define N 110 8 #define LD double 9 #define eps 1e-13 10 11 using namespace std; 12 13 int n,m,tot; 14 LD u[N],a[N][N]; 15 16 LD Gauss(LD a[N][N],int n) 17 { 18 int cnt=0; 19 for(int i=1;i<=n;i++) 20 { 21 int t=0; 22 for(int j=i;j<=n;j++) 23 if(fabs(a[j][i])>eps) 24 { 25 t=j; 26 break; 27 } 28 if(!t) 29 { 30 cnt++; 31 continue; 32 } 33 for(int j=1;j<=n+1;j++) swap(a[i][j],a[t][j]); 34 for(int j=i+1;j<=n+1;j++) a[i][j]/=a[i][i]; 35 a[i][i]=1.0; 36 for(int j=1;j<=n;j++) 37 { 38 if(j==i) continue; 39 for(int k=i+1;k<=n+1;k++) 40 a[j][k] -= a[j][i]*a[i][k]; 41 a[j][i]=0; 42 } 43 } 44 return a[n][n+1]/a[n][1]- a[1][n+1]/a[1][n]; 45 } 46 47 int main() 48 { 49 // freopen("test.txt","r",stdin); 50 while(~scanf("%d%d",&n,&m)) 51 { 52 memset(a,0,sizeof(a)); 53 int x,y; 54 LD R; 55 for(int i=1;i<=m;i++) 56 { 57 scanf("%d%d%lf",&x,&y,&R); 58 LD tmp=1.0/R; 59 a[x][x]+=tmp; 60 a[y][y]+=tmp; 61 a[x][y]-=tmp; 62 a[y][x]-=tmp; 63 } 64 a[1][1]=1; 65 for(int i=2;i<=n;i++) a[1][i]=0; 66 a[1][n+1]=0; 67 a[n][n+1]=1; 68 printf("%.2f\n",Gauss(a,n)); 69 } 70 return 0; 71 }