poj3532

算电阻

题目描述:

1和n之间的电阻.给出了节点之间导线以及电阻值.

题解:

高斯消元.之前先用电压法构造.统一标号减1.u0定为0,un-1待定.然后定u0到un-1的电流为1,算到方程组里.之后u0的方程组=0,然后每次电阻都写到方程组里,那么un-1算出来其实就是电阻值.

重点:

电位法,并且假设电流,转换方程.

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)

typedef long long ll;

using namespace std;

const int maxn = 100 + 10;
const double eps = 1e-8;
double a[maxn][maxn], x[maxn];
int equ, var;
int n, m;
double rs[maxn][maxn];

//int gauss()
//{
//int i,j,k,col,max_r;
//for(k=0,col=0;k<equ&&col<var;k++,col++)
//{
//max_r=k;
//for(i=k+1;i<equ;i++)
//if(fabs(a[i][col])>fabs(a[max_r][col]))
//max_r=i;
//if(fabs(a[max_r][col])<eps)return 0;
//if(k!=max_r)
//{
//for(j=col;j<var;j++)
//swap(a[k][j],a[max_r][j]);
//swap(x[k],x[max_r]);
//}
//x[k]/=a[k][col];
//for(j=col+1;j<var;j++)a[k][j]/=a[k][col];
//a[k][col]=1;
//for(i=0;i<equ;i++)
//if(i!=k)
//{
//x[i]-=x[k]*a[i][k];
//for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];
//a[i][col]=0;
//}
//}
//return 1;
//}

void gauss()
{
    for(int k=0,col=0; k<equ&&col<var; k++,col++)
    {
        int max_k = k;
        for(int i = k+1; i < equ; i++)
        {
            if(fabs(a[i][col]) > fabs(a[max_k][col]))
            {
                max_k = i;
            }
        }
        if(fabs(a[max_k][col]) < eps)
        {
            break;
        }
        if(max_k!=k)
        {
            swap(x[k], x[max_k]);
            for(int i = col; i<var; i++)
            {
                swap(a[k][i], a[max_k][i]);
            }
        }
        x[k] /= a[k][col];
        for(int i=col+1; i<var; i++)
        {
            a[k][i] /= a[k][col];
        }
        a[k][col]=1;
        for(int i=0; i < equ; i++)
        {
            if(i != k)
            {
                x[i] -= a[i][col]*x[k];
                for(int j=col+1; j < var; j++)
                {
                    a[i][j] -= a[i][col]*a[k][j];
                }
                a[i][col] = 0;
            }
        }
    }
}

void solve()
{
    CLR(a);
    CLR(x);
    CLR(rs);
    equ = n;
    var = n;
    a[0][0] = 1;
    x[0] = 0;

    for(int i = 1; i < n-1; i++)
    {
        x[i] = 0;
    }
    while(m--)
    {
        int x, y, r;
        scanf("%d%d%d", &x, &y, &r);
        double s = 1.0/r;
        x--;
        y--;
        rs[x][y]=rs[y][x]=s;
        if(x!=0)
        {
            a[x][x] += s;
            a[x][y] -= s;
        }
        if(y!=0)
        {
            a[y][y] += s;
            a[y][x] -= s;
        }
    }
    x[equ - 1] = 1;
    gauss();
    printf("%.2f\n", x[n-1]);
//    double ans = 0;
//    for(int i = 0;i < n -1;i++)
//    {
//        if(rs[n-1][i] != 0)
//            ans += (x[n-1]-x[i])*rs[n-1][i];
//    }
//    printf("%.2f\n", x[n-1]/ans);
}

int main()
{
    //freopen("11Kin.txt", "r", stdin);
    //freopen("1out.txt", "w", stdout);
    while(scanf("%d%d", &n, &m) != EOF)
    {
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值