hdu5006 两个节点间为0-1电阻,求总电阻:并查集缩点

目前高斯消元最后一题吧==

bug了一晚上,心好累

这题是鞍山网赛的,那时弱弱的都不知高斯消元这东西==

本题其实就是把电阻为0的点用并查集缩点在一起,想到这儿应该很容易错了,却因为两个问题错到现在

一个问题是高斯消元里面不能return 0这个比较奇怪,怎么修改精度都过不了,因为肯定有解,也就是说会导致方程无解?卧槽去了就能过了

还有一个问题是建立方程,其实不该设n个方程,因为有一个方程是多余的,去掉一个方程然后再加一个方程:强制某节点电势为0==好奇怪上次那个等效电阻写错了尼玛竟然A了==。。其实这个改不改都能过

好烦躁就这样吧。。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define eps 1e-8
 7 int row,col;
 8 double g[505][505],x[505];
 9 int father[10105],u[40105],v[40105],w[40105],id[10105];
10 int find(int y)
11 {
12   if (father[y]!=y) father[y]=find(father[y]);
13   return father[y];
14 }
15 int guass()
16 {
17   int tr,tc,i,j,max_r;
18   for (tr=1,tc=1;tc<=col;tc++)
19   {
20     max_r=tr;
21     for (i=tr;i<=row;i++)
22       if (fabs(g[i][tc])>fabs(g[max_r][tc])) max_r=i;
23 //    if (fabs(g[max_r][tc])<eps) return 0;
24     if (max_r!=tr)
25     {
26       for (j=tc;j<=col;j++) swap(g[max_r][j],g[tr][j]);
27       swap(x[max_r],x[tr]);
28     }
29     for (j=tc+1;j<=col;j++) g[tr][j]/=g[tr][tc];
30     x[tr]/=g[tr][tc]; g[tr][tc]=1;
31     for (i=1;i<=row;i++)
32     {
33       if (fabs(g[i][tc])<eps||i==tr) continue;
34       for (j=tc+1;j<=col;j++) g[i][j]-=g[tr][j]*g[i][tc];
35       x[i]-=x[tr]*g[i][tc]; g[i][tc]=0;
36     }
37     tr++;
38   }
39   return 1;
40 }
41 int main()
42 {
43   int T,n,m,s,t,i,j,cnt,id1,id2;
44   scanf("%d",&T);
45   while (T--)
46   {
47     scanf("%d%d%d%d",&n,&m,&s,&t);
48     memset(g,0,sizeof(g));
49     memset(x,0,sizeof(x));
50     for (i=1;i<=n;i++) father[i]=i;
51     for (i=1;i<=m;i++)
52     {
53       scanf("%d%d%d",&u[i],&v[i],&w[i]);
54       if (w[i]==0) father[find(u[i])]=find(v[i]);
55     }
56     if (find(s)==find(t)){
57       printf("0.000000\n"); continue; 
58     }//判是否无电阻
59     cnt=0;
60     memset(id,0,sizeof(id));
61     for (i=1;i<=n;i++) 
62       if (father[i]==i) id[i]=++cnt;
63     for (i=1;i<=n;i++)
64       if (!id[i]) id[i]=id[find(i)];//编号
65     for (i=1;i<=cnt;i++) father[i]=i;
66     for (i=1;i<=m;i++)
67       if (find(u[i])!=find(v[i])) father[find(u[i])]=find(v[i]);
68     if (find(s)!=find(t)){
69       printf("inf\n"); continue;
70     }//判是否连通
71     for (i=1;i<=m;i++)
72     {
73       id1=id[u[i]]; id2=id[v[i]];
74       if (id1==id2) continue;
75       g[id1][id1]--; g[id1][id2]++;
76       g[id2][id2]--; g[id2][id1]++;
77     }
78     x[id[s]]=-1; x[id[t]]=1;//建图
79     for (i=1;i<=cnt;i++) g[cnt][i]=0; x[cnt]=0; g[cnt][1]=1;
80     //强行删去一个表达式令任意一点电势为0
81     row=col=cnt;
82     guass();
83     printf("%.6lf\n",x[id[s]]-x[id[t]]+eps);
84   }
85   return 0;
86 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5006

posted on 2015-03-07 02:13  xiao_xin  阅读(118)  评论(0编辑  收藏  举报

导航