uva 10808 - Rational Resistors
来源:互联网 发布:ubuntu忘记登录密码 编辑:程序博客网 时间:2024/05/21 08:46
uva 10808 - Rational Resistors
题意:给出一个纯电阻网络,求任意两点间的等效电阻 , 输出分数形式。
看似简单的电路题用程序实现起来却非常棘手,首先得自己定义分数的各种运算,有不确long long 的精度是否够用。。
思路很简单,一个比较简单的方法是采用节点电压法(参见http://baike.baidu.com/link?url=tsPt2fO-B8N57v2A1LHvgaRkliFfSKUcEtZnTBxACzimkTYJTOaCY4IjKcOTds0TRenmLEyZAXCeJDIfP17Onq)
在待求两点间接一个1安培的电流源,根据节点电压法列方程组,解出两点间电压的差值在数值上等于两点间的等效电阻。
这题不太容易确定long long是否够用,如果要手写高精度分数,简直奔溃。。 还好在uva的讨论版上看到有人用long long 通过了。(写的不好依然会超出long long)
参考代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>#include <cstdlib>#include <map>#include <vector>#include <queue>#include <set>using namespace std;typedef long long LL;const int maxn = 20;//关于分数的一些定义,有些用没用到----------------struct Frac{ LL a,b; friend ostream& operator << (ostream & ,Frac &) ; friend istream& operator >> (istream & ,Frac &) ; friend Frac operator + (const Frac & , const Frac &); friend Frac operator - (const Frac & , const Frac &); friend Frac operator * (const Frac & , const Frac &); friend Frac operator / (const Frac & , const Frac &); void operator += (const Frac &f) {*this = *this + f ;} void operator -= (const Frac &f) {*this = *this - f ;} void operator *= (const Frac &f) {*this = *this * f ;} void operator /= (const Frac &f) {*this = *this / f ;} void init_zero(){a=0 ,b=1;} LL gcd(LL x,LL y){ return y==0 ? x : gcd(y , x%y); }; inline void simplify(){ LL r = gcd(a,b); if(r!=0) a /= r ,b/=r; } Frac(LL x=0,LL y=1) : a(x) , b(y) {simplify(); } bool isInf()const { return a!=0 && b==0 ; } bool isZero()const { return a==0 && b!=0 ;}};Frac operator + (const Frac & f1,const Frac &f2){ return Frac(f1.a*f2.b + f2.a*f1.b , f1.b*f2.b);}Frac operator - (const Frac & f1,const Frac &f2){ return Frac(f1.a*f2.b - f2.a*f1.b , f1.b*f2.b);}Frac operator * (const Frac & f1,const Frac &f2){ return Frac(f1.a*f2.a ,f1.b*f2.b);}Frac operator / (const Frac & f1,const Frac &f2){ return Frac(f1.a*f2.b , f1.b*f2.a);}ostream & operator << (ostream & out ,Frac & c){ c.simplify(); out<<abs(c.a)<<"/"<<abs(c.b); // 注意要输出绝对值 return out;}istream & operator >> (istream & in , Frac & c){ in>>c.a>>c.b; return in;}//---------------------分数定义结束--------------------------typedef Frac Mat[maxn][maxn];Mat A;Frac gauss(Mat A,int n,int u,int v){ if(u==v) return 0; int i,j,k,r; for(i=0;i<n;i++){ for(r=i;r<n;r++) if(A[r][i].a != 0) break; if(r >= n) continue; if(r!=i) for(int j=0;j<=n;j++) swap(A[i][j] , A[r][j]); /* 这么写会超精度 for(k=0 ; k<n ;k++) if(k!=i && !A[k][i].isZero()) { Frac f = A[k][i] / A[i][i]; for(j=n ; j>i ;j--) A[k][j] -= f * A[i][j]; A[k][i] = 0; } */ for(j = n ; j>i ;j--) A[i][j] /= A[i][i]; A[i][i] = 1; for(k=0 ; k<n ;k++) if(k!=i && !A[k][i].isZero()) { for(j=n ; j>i ;j--) A[k][j] -= A[k][i]* A[i][j]; A[k][i] = 0; } } return A[u][n]/A[u][u] - A[v][n]/A[v][v];}Frac conduct[maxn][maxn]; // 电导int fa[maxn];void fa_init(){ for(int i=0;i<maxn;i++) fa[i] = i;}int Find(int x){ return fa[x]==x ? x : fa[x] = Find(fa[x]);}void union_fa(int x,int y){ int fx = Find(x) , fy = Find(y); if(fx != fy) fa[fx] = fy;}Frac solve(int n , int u , int v){ int tn = 0 , id[20] , tu , tv; for(int i=0 ; i<n ;i++) { if(i==u) tu = tn; if(i==v) tv = tn; if(Find(i) == Find(u)) id[tn++] = i;// 与u,v不连通的点没写进方程组。 } tn++; for(int i=0;i<tn;i++) for(int j=0;j<=tn;j++) A[i][j].init_zero(); for(int i=0;i<tn-1;i++){ for(int j=0;j<tn-1;j++){ if(i==j) continue; A[i][i] += conduct[id[i]][id[j]]; // 自导之和 A[i][j] -= conduct[id[i]][id[j]]; // 互导之和 } } A[tu][tn] = 1; //1安培的电流源 A[tv][tn] = -1; A[tn-1][0] = 1;//接地点电压为零,方程即为 1*V = 0 return gauss(A,tn,tu,tv);}int main(){ //freopen("input.txt","r",stdin); ios::sync_with_stdio(0); int T , cas = 1; cin>>T; while(T--){ fa_init(); int n,m; cin>>n>>m; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) conduct[i][j].init_zero(); int u,v,r; while(m--){ cin>>u>>v>>r; if(u==v) continue; union_fa(u,v); conduct[u][v] += (Frac){1,r}; conduct[v][u] += (Frac){1,r}; } int Q; cout<<"Case #"<<cas++<<":"<<endl; cin>>Q; while(Q--){ cin>>u>>v; Frac ans; if(Find(u) != Find(v)) ans = (Frac){1 , 0}; // 若不连通,电阻为无穷大。 else if(u==v) ans = 0; else ans = solve(n , u , v); cout<<"Resistance between "<<u<<" and "<<v<<" is "<<ans<<endl; } cout<<endl; } return 0;}
0 0
- uva 10808 - Rational Resistors
- UVA 10808 - Rational Resistors 高斯消元
- uva 10808 - Rational Resistors(基尔霍夫定律+高斯消元)
- UVA 10808 - Rational Resistors(高斯消元+并查集+分数+基尔霍夫定律)
- UVA 4566 - Resistors
- uva 11657 - Rational Billiard(数学)
- Introduction to Resistors
- UVa 332 - Rational Numbers from Repeating Fractions
- Uva 7363 -- A rational Sequence(简单)
- UVA, 332 Rational Numbers from Repeating Fractions
- RATIONAL
- Rational
- 递归搜索 ( 水题 )——A Rational Sequence ( UVA 7363 )
- Hdu 3429 Resistors (分数模板 递归读入)
- Pull-up and Pull-down Resistors
- 精密电阻排行榜 List of Precision Resistors
- 硬件相关——Pull-up and Pull-down Resistors
- Rational Portfolio Manager、Rational ClearQuest、Rational ClearCase
- 一个简单的客户机服务器程序
- OJ_1006 ZOJ问题
- dojo省份地市级联之省份Dao接口类(三)
- 水星MW300R V6(MT7620)CPU引脚图
- cocos2dx 使用button控件
- uva 10808 - Rational Resistors
- c++中pragma预编译指令简介
- Linux下Daemon的实现
- cocos2d-x游戏开发系列教程-超级玛丽10-怪物与马里奥冲突检测
- 连续正整数问题
- cocos2dx使用cocostudio动画
- HTTPS 与SSL
- 教大家如何设置2个或多个路由器连接一个网线
- VC++ ^和gcnew