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 }