2014鞍山网络预选赛1010(缩点+高斯消元)hdu5006

Resistance

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 280    Accepted Submission(s): 82


Problem Description
Recently DRD got a number of wires. Some of the wires have the resistance 1 ohm while the others have the resistance 0 ohm. Each wire has probability 50% to be 0 ohm or 1 ohm.

Now ATM gets a circuit board. There are N points in the circuit board. DRD wants to connect these points using his wires. He chooses a wire randomly and chooses two points in the board randomly. Then he will connect the two points using the wire he chooses. DRD will use M wires. Note that it's possible that there exist two points which are not connected by wires.

ATM is interested in the equivalent resistance between the point S and point T. Since they lack of instruments, they want you to calculate the answer.
 

Input
The first line contains an integer T, denoting the number of the test cases.

For each test case: The first line contains 4 integers: N, M, S, and T. For each of the next M lines, it contains 3 integers: u, v, and c, representing that DRD uses a wire, whose resistance is c, to connect the point u and v. It's guaranteed that 1 <= N <= 10000 and M = 4*N. 1 <= u, v <= N. c is randomly chosen from {0, 1} and u and v are randomly chosen from {1, 2, ..., N}. Note that u can equal v.
 

Output
For each test case, output a real number. There must be exactly 6 digits after the decimal point. If S and T are not connected by wires, output "inf" (without quotes) instead.
 

Sample Input
   
   
2 10 40 6 1 9 4 1 7 3 1 10 1 0 5 2 0 6 7 1 7 3 1 3 5 1 3 6 1 8 10 0 8 3 0 7 3 1 3 9 1 2 8 1 10 5 0 10 2 1 10 9 1 9 1 0 7 5 1 10 2 0 8 1 0 2 8 0 10 2 0 1 5 0 5 4 0 7 4 1 8 5 1 4 3 1 6 1 1 5 10 0 3 9 1 5 1 0 9 2 1 3 4 1 5 8 0 3 5 1 3 4 1 2 7 0 4 4 0 1 8 0 10 10 0 10 40 2 1 5 6 1 8 10 1 3 8 1 8 5 0 6 4 1 9 9 1 3 6 1 2 4 1 9 8 0 9 3 0 7 7 1 8 6 1 10 4 1 1 3 0 2 8 1 9 8 0 8 1 1 6 4 0 3 4 0 1 4 0 1 10 0 9 10 0 6 1 1 3 1 1 5 4 0 1 2 1 7 2 1 10 9 0 6 1 0 10 3 1 8 6 1 1 4 0 1 1 0 4 3 0 1 8 0 7 10 1 10 6 0 4 5 0 2 2 0 4 2 1
 

Sample Output
   
   
0.333333 0.222222

题意:RT

思路:这其实是一道高中物理题,也是把我醉到不行

            首先注意,边的电阻为0是没有意义的,所以可以把所有相邻边为0的点给合并

            由于数据是随机的,所有合并点之后剩下的点也就不多了

            这里设每个点的电势为Ui,根据基尔霍夫电流定律,流入一个点的电流等于流出的电流
  
            那么对于任何点i都有∑(Ui-Uj)/Rij=0,其中点j为i的邻接点

            对于每个点都有这个式子,那么现在就是n个未知数,n个方程,正好可以用高斯消元来解

            为了方便得出解,可以给整个电路一个初始电流1安,从S点进,从T点出

            那么初始化的时候∑(Us-Uj)/Rsj=1,∑(Ut-Uj)/Rtj=-1,其它的这个值设为0

            因为电流只和电势差有关,那么这样初始化以后一定有无穷多个解,高斯消元是无法解的

            然后为了防止这种情况,我们可以假设其中一个节点(任何节点都行)的电势为一个常数,那么所有点的电势就固定了,就一定有解了

            因为初始化了电流为1安,那么答案就直接是(Us-Ut)/ 1,总电阻=总的电势差 / 总电流

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          using namespace std; const int MAXN = 10010; const double eps = 1e-8; double U[500][500]; int id[MAXN]; int fa[MAXN]; int vis[MAXN]; int eu[MAXN*4]; int ev[MAXN*4]; int mfind(int x) { if(x==fa[x])return x; else return fa[x]=mfind(fa[x]); } void guass(int n) { for(int i=0;i 
         
           =eps)break; } if(r==n)continue; for(int j=0;j<=n;j++)swap(U[i][j],U[r][j]); for(int j=n;j>i;j--)U[i][j]/=U[i][i]; U[i][i]=1; for(int j=0;j 
          
            i;k--)U[j][k]-=U[j][i]*U[i][k]; U[j][i]=0; } } } int main() { int t; scanf("%d",&t); while(t--){ int N,M,S,T; scanf("%d%d%d%d",&N,&M,&S,&T); for(int i=1;i<=N;i++)fa[i]=i; for(int i=0;i 
            
           
          
         
       
      
      
     
     
    
    
   
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值