BZOJ 2419: 电阻 [高斯消元 物理]

http://www.lydsy.com/JudgeOnline/problem.php?id=2419


 

题意:

n个点m个电阻构成一张图,求1到n的等效电阻


 

第一节课看一道题弃疗,于是来做这道物理题

orz PoPoQQQ大爷 http://blog.csdn.net/popoqqq/article/details/41703037

电流形成的图类似一个流网络,也满足流量平衡:(貌似好像有个叫基尔霍夫定律的玩意儿,然而我只知道基尔霍夫矩阵....)

令从$1$到$n$流的电流$I=1$,则:

$\sum\limits\frac{U_i-U_j}{R_{i,j}}=0$

$\sum\limits\frac{U_1-U_j}{R_{1,j}}=1$

$\sum\limits\frac{U_n-U_j}{R_{i,n}}=-1$

$U_n=0$

辣么答案就是$U_1$啦

一个点一个方程,然后高斯消元

怎么让$U_n=0$呢?这可是方程啊.............直接赋值就行了

 

实现上的小技巧:两点之间可能有多个电阻,所以直接保存电阻的倒数(电导)就好了,直接相加

我这个xx竟然忘记输出后换行了...

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=505;
int n,m,u,v;
double g[N][N],a[N][N],r;
void buildEquation(){
    for(int i=1;i<n;i++)
        for(int j=1;j<=n;j++)
            a[i][i]+=g[i][j],a[i][j]-=g[i][j];
    a[1][n+1]=1;
    a[n][n+1]=-1;
    a[n][n]=1;a[n][n+1]=0;
}
void GaussElimination(){
    for(int i=1;i<=n;i++){
        int r=i;
        for(int j=i+1;j<=n;j++)
            if(abs(a[j][i])>abs(a[r][i])) r=j;
        if(r!=i) for(int k=1;k<=n+1;k++) swap(a[i][k],a[r][k]);

        for(int j=i+1;j<=n;j++){
            double t=a[j][i]/a[i][i];
            for(int k=i;k<=n+1;k++) a[j][k]-=a[i][k]*t;
        }
    }
    for(int i=n;i>=1;i--){
        for(int j=n;j>i;j--) a[i][n+1]-=a[j][n+1]*a[i][j];
        a[i][n+1]/=a[i][i];
    }
}
void ini(){memset(g,0,sizeof(g));memset(a,0,sizeof(a));}    
int main(){
    freopen("in","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF){
        ini();
        for(int i=1;i<=m;i++){
            scanf("%d%d%lf",&u,&v,&r);
            if(u==v) continue;
            g[u][v]+=1/r;g[v][u]+=1/r;
        }
        buildEquation();
        GaussElimination();
        printf("%.2lf\n",a[1][n+1]);
    }
}
 

 

posted @ 2017-02-19 15:49  Candy?  阅读(588)  评论(0编辑  收藏  举报