SP2415 RESIST - Kirchhof Law
· 3 min read
题意简述
给定一张 个节点 条边的无向图,边权表示电阻阻值,求节点 到 的等效电阻。
参考资料
解题思路
设节点 的电势为 ,边 的电阻为 ,则电导为:
根据 欧姆定律,从 到 的电流为:
根据 基尔霍夫电流定律,对于任意一个普通节点,所有关联支路电流的代数和为 。
考虑节点 的电流:
展开可得:
这是一个关于各点电势的线性方程。
考虑添加一条边 ,设其电导为 。节点 的方程加入 ,节点 的方程加入 ,因此对应到系数矩阵就是:
把所有边的贡献都加到矩阵里,就得到了整个线性方程组。
我们可以在节点 通入 电流,并将节点 设为零电势点,求出节点 的电势。
利用 高斯消元 求解各点电势后,等效电阻为:
参考代码
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
const int N=105;
double a[N][N];
bool gauss(int n)
{
for(int i=1;i<=n;i++)
{
int t=i;
for(int j=i+1;j<=n;j++)
{
if(fabs(a[j][i])>fabs(a[t][i]))t=j;
}
if(fabs(a[t][i])<eps)return 0;
swap(a[i],a[t]);
for(int j=n+1;j>=i;j--)a[i][j]/=a[i][i];
for(int j=1;j<=n;j++)
{
if(i==j)continue;
for(int k=n+1;k>i;k--)a[j][k]-=a[i][k]*a[j][i];
}
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
while(cin>>n>>m)
{
while(m--)
{
int u,v;
double r;
cin>>u>>v>>r;
double g=1/r;
a[u][u]+=g;
a[u][v]-=g;
a[v][v]+=g;
a[v][u]-=g;
}
a[1][n+1]=1;
for(int i=1;i<n;i++)a[n][i]=0;
a[n][n]=1;
a[n][n+1]=0;
gauss(n);
cout<<fixed<<setprecision(2)<<a[1][n+1]<<'\n';
memset(a,0,sizeof a);
}
return 0;
}